CC2530和STM32F103之间的串口通信问题,求助!!

2019-07-18 15:41发布

      最近在写Zigbee网关通信程序,需要用到CC2530和STM32F103ZET6之间的串口通信。两者的串口配置都是一样的,CC2530之间可以进行通讯,STM32之间也可以进行通讯;STM32发CC2530收也可以正常通讯,但是CC2530发、STM32收就不能正常通讯,请问这是怎么回事?求大神指点,谢谢!
      我用万用表测了两者串口引脚的电平,STM32的TX端配置为推挽输出(电平为3.3V),RX端为浮空输入(电平为0.15V);CC2530串口0的两个引脚均为3.3V。 是不是电平兼容性的问题呢?若是有什么办法可以解决?
  1. 1)STM32串口通信程序:
  2. void uart1_init(u32 bound){
  3.   //GPIO端口设置
  4.   GPIO_InitTypeDef GPIO_InitStructure;
  5.     USART_InitTypeDef USART_InitStructure;
  6.     NVIC_InitTypeDef NVIC_InitStructure;
  7.       
  8.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
  9.    
  10.     //USART1_TX   GPIOA.9
  11.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  12.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  13.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   //复用推挽输出
  14.   GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
  15.      
  16.   //USART1_RX     GPIOA.10初始化
  17.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  18.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOAtiNG;//浮空输入
  19.   GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  
  20.      
  21.   //Usart1 NVIC 配置
  22.   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  //USART1中断通道
  23.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级3
  24.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;      //子优先级3
  25.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能
  26.     NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
  27.    
  28.    //USART 初始化设置
  29.     USART_InitStructure.USART_BaudRate = bound;//串口波特率
  30.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
  31.     USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
  32.     USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
  33.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
  34.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
  35.   
  36.   USART_Init(USART1, &USART_InitStructure); //初始化串口1
  37.   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  38.   USART_Cmd(USART1, ENABLE);                    //使能串口1
  39. }
  40. //USART1串口中断程序
  41. void USART1_IRQHandler(void)
  42. {
  43.     u8 res;
  44.      if(USART_GetITStatus(USART1,USART_IT_RXNE))
  45.   {
  46.      res= USART_ReceiveData(USART1);
  47.      USART_SendData(USART1,res);
  48.               
  49.         while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);   
  50.   }
  51. }
  52.   
  53.   
  54. 2)CC2530串口通信程序:
  55. #include <ioCC2530.h>
  56. #include <string.h>
  57. #define uint unsigned int
  58. #define uchar unsigned char
  59. //定义控制LED灯的端口
  60. #define LED1 P1_0    //定义LED1为P10口控制
  61. #define LED2 P1_1    //定义LED1为P11口控制
  62. //函数声明
  63. void Delayms(uint xms);    //延时函数
  64. void InitLed(void);        //初始化P1口
  65. void InitUart();           //初始化串口
  66. void Uart_Send_String(char *Data,int len);
  67. char Rxdata[50];
  68. uchar RXTXflag = 1;
  69. char temp;
  70. uchar  datanumber = 0;
  71. /****************************
  72.           延时函数
  73. *****************************/
  74. void Delayms(uint xms)   
  75. {
  76.   uint i,j;
  77.   for(i=xms;i>0;i--)
  78.     for(j=587;j>0;j--);
  79. }  
  80. /****************************
  81. //初始化程序
  82. *****************************/
  83. void InitLed(void)
  84. {
  85.   P1DIR |= 0x03; //P10、P11定义为输出
  86.   LED1 = 0;     //关LED1
  87.   LED2 = 0;     //关LD2
  88. }
  89.   
  90. /****************************************************************
  91.    串口初始化函数     
  92. ***********************************************************/
  93. void InitUart()
  94. {
  95.     CLKCONCMD &= ~0x40;      // 设置系统时钟源为 32MHZ晶振
  96.     while(CLKCONSTA & 0x40);    // 等待晶振稳定
  97.     CLKCONCMD &= ~0x47;      // 设置系统主时钟频率为 32MHZ
  98.     SLEEPCMD|=0x04;        //关闭不用的RC振荡器
  99.       
  100.     PERCFG = 0x00;           //使用串口1的备用位置1 P0口
  101.     P0SEL  = 0x3c;           //P0_2,P0_3,P0_4,P0_5用作串口,第二功能
  102.     P2DIR &= ~0XC0;         //P0优先作为UART0 ,优先级
  103.       
  104.     U0CSR |= 0x80;           //UART 方式
  105.     U0GCR |= 8;              //U0GCR与U0BAUD配合     
  106.     U0BAUD |= 59;           //波特率设为9600
  107.     UTX0IF = 1;              //UART0 TX 中断标志初始置位1  (收发时候)
  108.     U0CSR |= 0X40;           //允许接收
  109.     IEN0 |= 0x84;             //开总中断,接收中断   
  110. }
  111. /****************************************************************
  112. 串口发送字符串函数   
  113. ****************************************************************/
  114. void Uart_Send_String(char *Data,int len)
  115. {
  116.     int j;
  117.     for(j=0;j<len;j++)
  118.     {
  119.         U0DBUF = *Data++;
  120.         while(UTX0IF == 0);      //发送完成标志位
  121.         UTX0IF = 0;    //UART0 TX中断标志清0
  122.     }
  123. }
  124.   
  125.   
  126. /***************************
  127. //主函数
  128. ***************************/
  129. void main(void)
  130. {
  131.     InitLed();      //调用初始化函数
  132.     InitUart();
  133.     while(1)
  134.     {
  135.         
  136.       if(RXTXflag == 1) //接收状态
  137.         {
  138.             LED1=1;    //接收状态指示
  139.             if( temp != 0)
  140.             {
  141.                 //'#'被定义为结束字符,最多能接收50个字符
  142.                 if((temp!='#')&&(datanumber<50))
  143.                 {
  144.                     Rxdata[datanumber++] = temp;
  145.                 }
  146.                 else
  147.                 {
  148.                     RXTXflag = 3; //进入发送状态
  149.                     LED1=0;     //关指示灯
  150.                 }
  151.                 temp  = 0;
  152.             }
  153.         }
  154.         if(RXTXflag == 3)     //发送状态
  155.         {
  156.             LED2= 1;                           
  157.             U0CSR &= ~0x40;   //禁止接收
  158.             Uart_Send_String(Rxdata,datanumber); //发送已记录的字符串。
  159.             U0CSR |= 0x40;    //允许接收
  160.             RXTXflag = 1;     //恢复到接收状态
  161.             datanumber = 0;    //指针归0
  162.             LED2 = 0;         //关发送指示
  163.         }  
  164.     }
  165. }
  166. /****************************************************************
  167. 串口接收一个字符: 一旦有数据从串口传至CC2530, 则进入中断,
  168. 将接收到的数据赋值给全局变量temp.
  169. ****************************************************************/
  170. #pragma vector = URX0_VECTOR
  171. __interrupt void UART0_ISR(void)
  172. {
  173.     URX0IF = 0;    //清中断标志
  174.     temp = U0DBUF;                           
  175. }
复制代码

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
2条回答
645550074
2019-07-18 22:44
就你这个程序,你应该想达到的效果是cc2530发什么就应该收到什么,但是cc2530接收数据到存入缓存Rxdata[datanumber++]都是要放在中断中处理,这样才能保持实时性和正确的接收,例如在两次接收中断间没有处理到Rxdata[datanumber++]=temp; 那不是第一中断的数据temp没有放入缓存去吗?

一周热门 更多>