将Shell移植到串口上(二)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
一、程序修改过程
1、添加新任务
在开始任务文件中,添加串口命令处理任务,如下所示。
//开启系统时钟。
SysTick_CounterCmd(SysTick_Counter_Enable);
//进行统计任务初始化
OSStatInit();
//创建两个消息队列,分别用于按键消息和串口命令。
KeyValueOSQ=OSQCreate(&KeyMsg_Tbl[0],30);
UartMsgOSQ=OSQCreate(&UartMsg_Tbl[0],30);
//除了开始任务在主函数中创建,其他任务都在开始任务中创建
OSTaskCreate(Task_KeyScan,(void *)0,&Task_KeyScanStk[TaskStk_Size-1],Task_KeyScan_Prio);
OSTaskCreate(Task_CmdShell,(void *)0,&Task_CmdShellStk[TaskStk_Size-1],Task_CmdShell_Prio);
OSTaskCreate(Task_UartCmd,(void *)0,&Task_UartCmdStk[TaskStk_Size-1],Task_UartCmd_Prio);
2、修改任务文件task_uartcmd.c
在按键消息处理任务文件的基础上进行修改,所有的变量定义和函数定义前加一个Uart。很快就编译通过了。
3、添加文件uart.c
主要完成以下几个函数:
void Uart_ReceiveChar (void); //在中断函数中调用,接受字符,并发送到消息队列
void Uart_PutString(u8* Str); //在串口输出字符串
void Uart_PutChar( u8 CharValue ); //在串口输出字符,若是格式化需要处理,在这里完成
void Uart_SendChar( u8 CharValue ); //单纯在串口输出字符。写入ascii码。
u8 Uart_GetChar(void); //从消息队列获取字符
4、进行串行口的配置
void UART_Config(void){ //进行串口的初始化配置
GPIO_InitTypeDef GPIO_InitStructure; //进行GPIO端口设置的数据结构
USART_InitTypeDef USART_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; /* UART的发送引脚 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; /* UART的接收引脚 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200; //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1
USART_InitStructure.USART_Parity = USART_Parity_No ; //无奇偶校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送、接受模式有效
USART_Init(USART1, &USART_InitStructure); /* 根据上面结构的参数对串口1进行初始化 */
USART1->BRR =0x0271; /* 库函数的串口波特率计算有些问题,这里重新计算了一下 */
USART_Cmd(USART1, ENABLE); /* 使能串口1 */
}
二、接下来开始调试
1、首先编译、下载
编译过程中有些小的问题,很快解决。
程序运行,中断显示h>,前面那个s上哪儿去了?用串口调试器打开串口看一下:的确只收到的两个字符,什么原因呢?单步调试可以完整显示sh>,但是全速运行又只有h>了。
串口接收中断没有打开,字符接收没有工作。
2、打开串口接收中断
USART_ITConfig ( USART1, USART_IT_RXNE, ENABLE );这样应该使能接受中断了吧,但是接受还是没有反应。想起来了,NVIC还没有设置。
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
3、最终发现问题:因为没有使用消息内容数组,直接用串口接收到的值冒充指针。
void Uart_ReceiveChar (void) {
u32 RecChar;
RecChar = (u32)(USART1->DR & 0xFF);
OSQPost ( UartMsgOSQ, ( void* )RecChar ); //将字符指针化放入消息队列
}
最后在从消息队列取出信息的时候用法不对,参考了<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />周航慈教授的书才改正过来。
正确的取值方法是这样的。
u8 Uart_GetChar(void){
u8 Err;
u8 TempChar;
TempChar =(u8) ( (u32) (u32*) OSQPend ( UartMsgOSQ, 0, &Err ) &0xFF );
return TempChar;
}
4、编译、下载成功,串口已经可以正常使用命令了。今天就到这里,明天再总结一下。
文章评论(0条评论)
登录后参与讨论