你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】在STM32F103上实现串口功能及消息邮箱-2

[复制链接]
STMCU-管管 发布时间:2021-5-21 11:31
如果您是完全按照《如何将移植ucos到STM32F103开发板上-1》来新建的工程的话,那很遗憾,你要重新建立一个工程,因为,在那篇文章的步骤1中,我们选中了GPIO,但是没有选中USART,所以要新建一个工程,只是也要把USART选中


BSP.c文件中增加对串口的初始化及中断的初始化:

  1. void NVIC_Configuration(void)
  2. {
  3.   //EXTI_InitTypeDef EXTI_InitStructure;
  4.   NVIC_InitTypeDef NVIC_InitStructure;
  5.   
  6.   /* Configure the NVIC Preemption Priority Bits */  
  7.   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

  8.   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  9.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  10.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  11.   NVIC_Init(&NVIC_InitStructure);
  12. }

  13. void USART_Config(USART_TypeDef* USARTx,u32 baud){
  14.   USART_InitTypeDef USART_InitStructure;
  15.   GPIO_InitTypeDef GPIO_InitStructure;

  16.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  17.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);       
  18.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  19.   
  20.   //usart_init----------------------------------------------------
  21.   /* Configure USART1 Rx (PA.10) as input floating */
  22.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  23.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  24.   GPIO_Init(GPIOA, &GPIO_InitStructure);                                         
  25.   
  26.   /* Configure USART1 Tx (PA.09) as alternate function push-pull */
  27.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  28.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  29.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  30.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  31.   
  32.   
  33.   USART_InitStructure.USART_BaudRate =baud;
  34.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  35.   USART_InitStructure.USART_StopBits = USART_StopBits_1;
  36.   USART_InitStructure.USART_Parity = USART_Parity_No;
  37.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  38.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  39.   /* Configure USART1 */
  40.   USART_Init(USARTx, &USART_InitStructure);

  41.   /* Enable USART1 Receive and Transmit interrupts */
  42.   USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);
  43.   //USART_ITConfig(USARTx, USART_IT_TXE, ENABLE);

  44.   
  45.   /* Enable the USART1 */
  46.   USART_Cmd(USARTx, ENABLE);       

  47.   //USART_ClearFlag(USARTx, USART_FLAG_TXE);
  48. }

  49. void BSP_Init(void)
  50. {
  51.   /* System Clocks Configuration --72M*/
  52.   RCC_Configuration();   
  53.   GPIO_Configuration();

  54.   NVIC_Configuration();
  55.   USART_Config(USART1,115200);
  56. }
复制代码
APP目录下新建USART.c文件,添加如下代码:
  1. #include <usart.h>

  2. void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...){
  3.         const char *s;
  4.         int d;

  5.         char buf[16];
  6.         va_list ap;
  7.         va_start(ap, Data);

  8.         while(*Data!=0){
  9.                 if(*Data==0x5c){
  10.                         switch (*++Data){
  11.                                 case 'r':
  12.                                         USART_SendData(USARTx, 0x0d);

  13.                                         Data++;
  14.                                         break;
  15.                                 case 'n':
  16.                                         USART_SendData(USARTx, 0x0a);       
  17.                                         Data++;
  18.                                         break;

  19.                                 default:
  20.                                         Data++;
  21.                                         break;
  22.                         }
  23.                 }else if(*Data=='%'){
  24.                         switch (*++Data){
  25.                                 case 's':
  26.                                         s = va_arg(ap, const char *);
  27.                                         for ( ; *s; s++) {
  28.                                                 USART_SendData(USARTx,*s);
  29.                                                 while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
  30.                                         }
  31.                                         Data++;
  32.                                         break;
  33.                                 case 'd':
  34.                                         d = va_arg(ap, int);
  35.                                         itoa(d, buf, 10);
  36.                                         for (s = buf; *s; s++) {
  37.                                                 USART_SendData(USARTx,*s);
  38.                                                 while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
  39.                                         }
  40.                                         Data++;
  41.                                         break;
  42.                                 default:
  43.                                         Data++;
  44.                                         break;
  45.                         }                 
  46.                 }else{
  47.                         USART_SendData(USARTx, *Data++);
  48.                 }
  49.                 while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
  50.         }
  51. }

  52. char *itoa(int value, char *string, int radix)
  53. {
  54.         int     i, d;
  55.         int     flag = 0;
  56.         char    *ptr = string;

  57.         /* This implementation only works for decimal numbers. */
  58.         if (radix != 10)
  59.         {
  60.                 *ptr = 0;
  61.                 return string;
  62.         }

  63.         if (!value)
  64.         {
  65.                 *ptr++ = 0x30;
  66.                 *ptr = 0;
  67.                 return string;
  68.         }

  69.         /* if this is a negative value insert the minus sign. */
  70.         if (value < 0)
  71.         {
  72.                 *ptr++ = '-';
  73.                 /* Make the value positive. */
  74.                 value *= -1;
  75.         }
  76.         for (i = 10000; i > 0; i /= 10)
  77.         {
  78.                 d = value / i;

  79.                 if (d || flag)
  80.                 {
  81.                         *ptr++ = (char)(d + 0x30);
  82.                         value -= (d * i);
  83.                         flag = 1;
  84.                 }
  85.         }

  86.         /* Null terminate the string. */
  87.         *ptr = 0;

  88.         return string;

  89. } /* NCL_Itoa */

  90. int SendChar (int ch)  {                /* Write character to Serial Port     */
  91.   USART_SendData(USART1, (unsigned char) ch);
  92.   while (!(USART1->SR & USART_FLAG_TXE));
  93.         if(ch=='\r')
  94.                 SendChar('\n');
  95.   return (ch);
  96. }

复制代码
新建usart.h文件:
  1. <pre name="code" class="html">#ifndef __USART_H__
  2. #define __USART_H__

  3. #include <includes.h>

  4. void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...);
  5. char *itoa(int value, char *string, int radix);
  6. int SendChar (int ch);

  7. #endif
复制代码
stm32f10x_it.c文件中添加串口中断处理:
  1. void USART1_IRQHandler(void)
  2. {
  3.         unsigned int i;
  4.         unsigned char msg[50];
  5.         OS_CPU_SR  cpu_sr;

  6.         OS_ENTER_CRITICAL();
  7.         OSIntNesting++;

  8.         OS_EXIT_CRITICAL();

  9.         //OSTimeTick();

  10.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  11.         {       
  12.                 if(RxCounter1>20)
  13.                         RxCounter1=1;

  14.                 // Read one byte from the receive data register
  15.                 msg[RxCounter1++]= USART_ReceiveData(USART1);
  16.                 SendChar(msg[RxCounter1-1]);

  17.                 if(msg[RxCounter1-1]=='L')
  18.                 {
  19.                         msg[0]='L'; RxCounter1=1;
  20.                 }else if(msg[RxCounter1-1]=='F')
  21.                 {
  22.                         for(i=0; i< RxCounter1; i++){
  23.                                 TxBuffer1[i]        =msg[i];
  24.                         }
  25.                         TxBuffer1[RxCounter1]=0;
  26.                         RxCounter1=0;
  27.                         //OSSemPost(Com1_SEM);           
  28.                         OSMboxPost(Com1_MBOX,(void *)&msg);                            
  29.                 }
  30.         }
  31.         if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
  32.         {
  33.                 USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
  34.         }       
  35.         OSIntExit();
  36. }
复制代码
APP.c文件中新建消息邮箱处理函数:

  1. static  void Task_Com1(void *p_arg){
  2.         INT8U err;       
  3.         unsigned char * msg;
  4.         (void)p_arg;                                            
  5.         while(1){
  6.                 msg=(unsigned char *)OSMboxPend(Com1_MBOX,0,&err);
  7.                 if(msg[0]=='L'&&msg[1]=='1'){
  8.                         milsec1=atoi(&msg[3]);
  9.                         USART_OUT(USART1,"\r\n");
  10.                         USART_OUT(USART1,"LED1: %d ms delay",milsec1);
  11.                         USART_OUT(USART1,"\r\n");
  12.                 }else if(msg[0]=='L'&&msg[1]=='2'){
  13.                         milsec2=atoi(&msg[3]);
  14.                         USART_OUT(USART1,"\r\n");
  15.                         USART_OUT(USART1,"LED2: %d ms delay",milsec2);
  16.                         USART_OUT(USART1,"\r\n");
  17.                 }
  18.         }
  19. }
复制代码
并添加该任务:
  1. OSTaskCreateExt(Task_Com1,(void *)0,(OS_STK *)&Task_Com1Stk[Task_Com1_STK_SIZE-1],
  2.                 Task_Com1_PRIO,Task_Com1_PRIO,(OS_STK *)&Task_Com1Stk[0],
  3.                 Task_Com1_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
复制代码
新建一个头文件globals.h:
  1. #ifdef GLOBALS
  2. #define EXT
  3. #else
  4. #define EXT extern
  5. #endif


  6. EXT unsigned char TxBuffer1[400];

  7. EXT unsigned char TxBuffer2[];
  8. EXT unsigned char RxBuffer1[400];
  9. EXT unsigned char RxBuffer2[];
  10. EXT unsigned char TxCounter1;
  11. EXT unsigned int TxCounter2;
  12. EXT volatile unsigned int RxCounter1;
  13. EXT volatile unsigned int RxCounter2;

  14. EXT volatile unsigned char rec_f,tx_flag;
  15. EXT volatile unsigned long Rec_Len;       
  16. EXT volatile unsigned  int  milsec1,milsec2,milsec3;
复制代码
将 globals.h 文件 include 到 APP.c 和 stm32f10x_it.c 中,注意,在APP.c文件 中应该先define GLOBALS,即
  1. #define GLOBALS

  2. #include <globals.h>
复制代码
APP.c文件中添加全局变量:
  1. OS_EVENT* Com1_MBOX;
复制代码

stm32f10x_it.c 中也添加该变量:
  1. extern OS_EVENT* Com1_MBOX;
复制代码


收藏 评论0 发布时间:2021-5-21 11:31

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版