实验连接示意图

所用器材列表
硬件
- STM32F103核心板一块
- microUSB线
- STLinkban板和USB串口板
软件
- 交叉编译软件
实验步骤、操作的命令和结果
连接STM32和其他设备
写一个自己的建议bootloader,能通过串口执行两条最简单的指令:
- peek addr以一个字为单位读取内存中addr位置的数据,并以十六进制的形式输出
- poke addr data以一个字为单位修改内存中addr位置的数据为data
源代码
输入输出接口
1
|
void myPutc(char ch) {
HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,100);
}
void myPuts(char *str) {
for (int i = 0; i < strlen(str); i++)
myPutc(str[i]);
}
int8_t myGetc(uint8_t *c, uint16_t time_bound) {
while (time_bound) {
if (uart_rev.front != uart_rev.rear) {
*c = *uart_rev.front;
uart_rev.front++;
if (uart_rev.front >= buf + BUFSIZE)
uart_rev.front = buf;
return 0;
}
time_bound--;
}
return (int8_t) – 1;
}
int8_t myGets(uint8_t *str, uint16_t bound) {
int count = 0;
bound--;
while (count < bound) {
if (uart_rev.front != uart_rev.rear) {
char ch = *uart_rev.front;
uart_rev.front++;
if (uart_rev.front > buf + BUFSIZE)
uart_rev.front = buf;
if (ch == '\r')
break;
*str = ch;
if (ch != ' ') {
str++;
count++;
}
}
}
*str = '\0';
return count;
}
|
中断处理
1
| void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
uint8_t ret = HAL_OK;
char ch = *uart_rev.rear;
myPutc(ch);
if (c == '\r')
myPutc('\n');
uart_rev.rear++;
if (uart_rev.rear > buf + BUFSIZE)
uart_rev.rear = buf;
if (uart_rev.rear == uart_rev.front) {
uart_rev.front++;
if (uart_rev.front > buf + BUFSIZE)
uart_rev.front = buf;
}
do{
}while(HAL_UART_Receive_IT(UartHandle, uart_rev.rear, 1) != HAL_OK);
}
void USART1_IRQHandler(void){
HAL_UART_IRQHandler(&huart1);
}
|
命令处理
while (1) {
char cmd[MAXLEN];
char s2[MAXLEN];
count = 0;
myPuts("Please input your instruction: ");
count = myGets((uint8_t*)s1, MAXLEN);
sscanf(s1, "%s", cmd);
if (strcmp(cmd, "peek") == 0) {
int addr;
int res = sscanf(s1 + PEEKLEN, “%x %s”, &addr, s2);
if (res == 1) {
sprintf(s2, "peek: %x %x\r\n, addr, *((int *)addr)");
myPuts(s2);
}
else myPuts("error\r\n");
}
else if (strcmp(cmd, "poke") == 0) {
int addr, data;
int res = sscanf(str + POKELEN, "%x %x %s", &addr, &data, s);
if (res == 2) {
*((int *)addr) = data;
sprintf(s2, "poke: %x %x\r\n", addr, *((int *)addr));
myPuts(s2);
}
else myPuts("error\r\n");
}
else myPuts("error\r\n");
}
结果与分析
poke命令执行完之后,peek对应地址能得到正确的数据,符合实验预期。