CC2530和STM32F103之间的串口通信问题,求助!
时间:10-02
整理:3721RD
点击:
最近在写Zigbee网关通信程序,需要用到CC2530和STM32F103ZET6之间的串口通信。两者的串口配置都是一样的,CC2530之间可以进行通讯,STM32之间也可以进行通讯;STM32发CC2530收也可以正常通讯,但是CC2530发、STM32收就不能正常通讯,请问这是怎么回事?求大神指点,谢谢!
我用万用表测了两者串口引脚的电平,STM32的TX端配置为推挽输出(电平为3.3V),RX端为浮空输入(电平为0.15V);CC2530串口0的两个引脚均为3.3V。 是不是电平兼容性的问题呢?若是有什么办法可以解决?
我用万用表测了两者串口引脚的电平,STM32的TX端配置为推挽输出(电平为3.3V),RX端为浮空输入(电平为0.15V);CC2530串口0的两个引脚均为3.3V。 是不是电平兼容性的问题呢?若是有什么办法可以解决?
- 1)STM32串口通信程序:
- void uart1_init(u32 bound){
- //GPIO端口设置
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
-
- //USART1_TX GPIOA.9
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
-
- //USART1_RX GPIOA.10初始化
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
- GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
-
- //Usart1 NVIC 配置
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //USART1中断通道
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级3
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
- NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
-
- //USART 初始化设置
- USART_InitStructure.USART_BaudRate = bound;//串口波特率
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
- USART_InitStructure.USART_StopBits = USART_StopBits_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
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
- USART_Cmd(USART1, ENABLE); //使能串口1
- }
- //USART1串口中断程序
- void USART1_IRQHandler(void)
- {
- u8 res;
- if(USART_GetITStatus(USART1,USART_IT_RXNE))
- {
- res= USART_ReceiveData(USART1);
- USART_SendData(USART1,res);
-
- while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
- }
- }
-
-
- 2)CC2530串口通信程序:
- #include <ioCC2530.h>
- #include <string.h>
- #define uint unsigned int
- #define uchar unsigned char
- //定义控制LED灯的端口
- #define LED1 P1_0 //定义LED1为P10口控制
- #define LED2 P1_1 //定义LED1为P11口控制
- //函数声明
- void Delayms(uint xms); //延时函数
- void InitLed(void); //初始化P1口
- void InitUart(); //初始化串口
- void Uart_Send_String(char *Data,int len);
- char Rxdata[50];
- uchar RXTXflag = 1;
- char temp;
- uchar datanumber = 0;
- /****************************
- 延时函数
- *****************************/
- void Delayms(uint xms)
- {
- uint i,j;
- for(i=xms;i>0;i--)
- for(j=587;j>0;j--);
- }
- /****************************
- //初始化程序
- *****************************/
- void InitLed(void)
- {
- P1DIR |= 0x03; //P10、P11定义为输出
- LED1 = 0; //关LED1
- LED2 = 0; //关LD2
- }
-
- /****************************************************************
- 串口初始化函数
- ***********************************************************/
- void InitUart()
- {
- CLKCONCMD &= ~0x40; // 设置系统时钟源为 32MHZ晶振
- while(CLKCONSTA & 0x40); // 等待晶振稳定
- CLKCONCMD &= ~0x47; // 设置系统主时钟频率为 32MHZ
- SLEEPCMD|=0x04; //关闭不用的RC振荡器
-
- PERCFG = 0x00; //使用串口1的备用位置1 P0口
- P0SEL = 0x3c; //P0_2,P0_3,P0_4,P0_5用作串口,第二功能
- P2DIR &= ~0XC0; //P0优先作为UART0 ,优先级
-
- U0CSR |= 0x80; //UART 方式
- U0GCR |= 8; //U0GCR与U0BAUD配合
- U0BAUD |= 59; //波特率设为9600
- UTX0IF = 1; //UART0 TX 中断标志初始置位1 (收发时候)
- U0CSR |= 0X40; //允许接收
- IEN0 |= 0x84; //开总中断,接收中断
- }
- /****************************************************************
- 串口发送字符串函数
- ****************************************************************/
- void Uart_Send_String(char *Data,int len)
- {
- int j;
- for(j=0;j<len;j++)
- {
- U0DBUF = *Data++;
- while(UTX0IF == 0); //发送完成标志位
- UTX0IF = 0; //UART0 TX中断标志清0
- }
- }
-
-
- /***************************
- //主函数
- ***************************/
- void main(void)
- {
- InitLed(); //调用初始化函数
- InitUart();
- while(1)
- {
-
- if(RXTXflag == 1) //接收状态
- {
- LED1=1; //接收状态指示
- if( temp != 0)
- {
- //'#'被定义为结束字符,最多能接收50个字符
- if((temp!='#')&&(datanumber<50))
- {
- Rxdata[datanumber++] = temp;
- }
- else
- {
- RXTXflag = 3; //进入发送状态
- LED1=0; //关指示灯
- }
- temp = 0;
- }
- }
- if(RXTXflag == 3) //发送状态
- {
- LED2= 1;
- U0CSR &= ~0x40; //禁止接收
- Uart_Send_String(Rxdata,datanumber); //发送已记录的字符串。
- U0CSR |= 0x40; //允许接收
- RXTXflag = 1; //恢复到接收状态
- datanumber = 0; //指针归0
- LED2 = 0; //关发送指示
- }
- }
- }
- /****************************************************************
- 串口接收一个字符: 一旦有数据从串口传至CC2530, 则进入中断,
- 将接收到的数据赋值给全局变量temp.
- ****************************************************************/
- #pragma vector = URX0_VECTOR
- __interrupt void UART0_ISR(void)
- {
- URX0IF = 0; //清中断标志
- temp = U0DBUF;
- }
都是3.3V的吧,你共地了么?
就你这个程序,你应该想达到的效果是cc2530发什么就应该收到什么,但是cc2530接收数据到存入缓存Rxdata[datanumber++]都是要放在中断中处理,这样才能保持实时性和正确的接收,例如在两次接收中断间没有处理到Rxdata[datanumber++]=temp; 那不是第一中断的数据temp没有放入缓存去吗?