OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4747|回复: 2

串口1是RS485通信,使用收发中断,当我上位机发送数据到串口1后,一会儿就使其他设备都不工作

[复制链接]

10

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2016-1-21
在线时间
30 小时
发表于 2016-1-26 17:42:28 | 显示全部楼层 |阅读模式
10金钱
问题补充:芯片stm32f103zet6,当我从上位机发送启动命令到板子后,板子成功接收到数据并显示在屏上,但是10几秒后,我的其他串口都不工作,串口1的接收端的led灯会一闪一闪,点击串口屏也没反应。但是我在调试状态运行程序时,并没有这样的情况出现,调试状态下运行不会卡死。
求大神们提点一下意见,到底是哪除了问题?


#define RS485_send1()                          GPIOA->ODR |= (1<<8)
#define RS485_receive1()                  GPIOA->ODR &=~(1<<8)

//串口1初始化
void InitUART1(unsigned long pclk2,unsigned long bound)
{
                float temp;
                unsigned short mantissa;
                unsigned short fraction;
                temp = (float)(pclk2*1000000)/(bound*16);        //得到UARTDIV
                mantissa = temp;                                               //得到整数部分
                fraction = (temp-mantissa)*16;                        //得到小数部分
                mantissa<<=4;
                mantissa += fraction;
                RCC->APB2ENR |= (1<<2);                                //使能GPIOA时钟
                RCC->APB2ENR |= (1<<14);                        //使能串口1时钟
                GPIOA->CRH &= 0xFFFFF00F;                //PA9、PA10清零
                GPIOA->CRH |= 0x000008b0;                //1000(上下拉输入) 1011(复用推挽输出,50MHz)
                RCC->APB2RSTR |= 1<<14;                        //复位串口1
                RCC->APB2RSTR &=~(1<<14);                //停止复位
                //波特率设置
                USART1->BRR = mantissa;                        
                USART1->CR1 |= 0x200C;                        //1位停止,无校验

                USART1->CR1 |= 1<<8;
                MY_NVIC_Init(2,0,USART1_IRQChannel,2);//中断初始化,组2
                Uart1_RS485_Receive();      
}

//串口1配置为485接收
void        Uart1_RS485_Receive(void)    //接收
{
        RS485_receive1();//485CTL1置为低电平
        __nop();
        __nop();
        __nop();
        USART1->CR1 &=~(BIT(7)|BIT(3));        //发送禁止,发送中断禁止
        USART1->CR1 |= (BIT(5)|BIT(2));                //接收使能,接收中断使能
        USART1->SR         &=~(BIT(5));                //清除接收标志位
}

//串口1配置为485发送
void        Uart1_RS485_Send(void)     //发送
{
        RS485_send1();        //485CTL0置为高电平
        __nop();
        __nop();
        __nop();
        USART1->CR1 &=~(BIT(5)|BIT(2));        //接收禁止,接收中断禁止
        USART1->CR1 |= (BIT(7)|BIT(3));                //发送使能,发送中断使能
}

//发送数据
void uSendData_UART1(void)
{
        tUart1.uSendTail = 0;
        _delay_us(10);
        tUart1.uComStateflag = 0x10;//设置为发送状态
        if ((tUart1.uFuncID == REC_ORDER_APCODATA_M)||(tUart1.uFuncID == REC_ORDER_APCODATA_S))
        {
                tUart1.uSendBuf = 22;
        }
        else
        {
                tUart1.uSendBuf = common_conf.p_conf_equipment.b_equipment_number;
        }
        tagged_word.checksum = 0;
        tagged_word.checksum += tUart1.uSendBuf;
        USART1->DR = tUart1.uSendBuf;tUart1.uSendTail++;
        Uart1_RS485_Send();
}

//串口1中断服务函数
void USART1_IRQHandler(void)
{
/////////////接收中断
                unsigned char        cRead;
                if(USART1->SR&(1<<5))        //接收到数据
                {                               
                        cRead = USART1->DR;
                        if (tUart1.uComStateflag == 0x21)//接收数据状态
                        {
                                if (tUart1.uRecTimer15 >= 120)
                                {
                                        tUart1.uRecTimeout15flag = 1;
                                }
                                if (tUart1.uRecTop <= 0xFFFF)
                                {
                                        tUart1.uRecBuf[tUart1.uRecTop++] = cRead;
                                }
                        }
                        else
                        {
                                if (tUart1.uComStateflag == 0x00)
                                {
                                        tUart1.uLead_bytes[tUart1.uLead_byte] = cRead;
                                        if (tUart1.uLead_byte == 6)
                                        {
                                                tUart1.uLead_byte = 0;
                                                tUart1.uComStateflag = 0x20;
                                                if (cRead == common_conf.p_conf_equipment.b_equipment_number)
                                                {
                                                        tUart1.uRecOrderTimer = 0;
                                                        p_global_variable.upper_online_flag = 1;//联机状态
                                                       
                                                        tUart1.uResponseTimer = 0;//响应超时计时器清零
                                                        tUart1.uComStateflag = 0x21;//通讯状态设置为接收数据状态
                                                        tUart1.uRecTop = 0;
                                                        tUart1.uRecBuf[tUart1.uRecTop++] = cRead;
                                                        CRC_Result[0] = Cal_CRC16(cRead,0xFFFF);
                                                }
                                        }
                                        else if ((tUart1.uLead_byte%2) == 0)
                                        {
                                                if (cRead == 0xAA)
                                                {
                                                        tUart1.uLead_byte++;
                                                }
                                        }
                                        else if ((tUart1.uLead_byte%2) == 1)
                                        {
                                                if (cRead == 0x55)
                                                {
                                                        tUart1.uLead_byte++;
                                                }
                                        }
                                       
                                }
                        }
                        tUart1.uRecTimer15 = 0;
                        tUart1.uRecTimer35 = 0;
                }
//////////发送中断
                if((USART1->SR&(1<<7))&&(GPIOA->ODR&(1<<8)))        //发送数据寄存器为空&&RS485的DE/RE脚为高电平
                {               
                        _delay_us(20);
                        if (tUart1.uSendTail < tUart1.uSendTop)
                        {
                                response_datas();//响应数据处理
                                USART1->DR = tUart1.uSendBuf;
                                tUart1.uSendTail++;
                        }
                        else
                        {
                                USART1->CR1 &=~(1<<7);
                                tUart1.uLead_byte = 0;
                                tUart1.uSendTail = 0;
                                tUart1.uSendTop  = 0;
                                tUart1.uComStateflag = 0x11;//通讯状态设置为发送完成状态
                                tUart1.uResponseTimer = 0;//响应超时计时器清零
                                Uart1_RS485_Receive(); //开启485接收中断
                        }
                }
}

//定时器3中断,100us中断一次
void TIM3_IRQHandler(void)
{
        if(TIM3->SR&0X0001)//溢出中断
        {
                //TIM3中断执行程序
                        u_1msTimer1++;
                if (u_1msTimer1 >= 10)//1ms
                {
                        u_1msTimer1 = 0;
                       
                        if (tUart1.uComStateflag == 0x11)//发送完成状态
                        {
                                if ((tUart1.uResponse_flag == 1)&&(p_global_variable.machine_state_flag == FLAG_STATE_FINISH))
                                {
                                        tUart1.uResponse_flag = 2;//完成截止数据上传
                                }
                                else if ((tUart1.uResponse_flag == 2)&&(p_global_variable.machine_state_flag == FLAG_STATE_FINISH))
                                {
                                        tUart1.uResponse_flag = 3;//完成截止数据上传
                                        tUart1.uResponse_succeed_Timer = 0;//发送成功计时
                                }
                                tUart1.uComStateflag = 0x00;//通讯状态设置为空闲状态
                        }
                        if (tUart1.uComStateflag == 0x22)//接收完成状态
                        {
                                tUart1.uResponseTimer++;//响应超时计时
                                if (tUart1.uResponseTimer >= 500)//响应超时500ms
                                {
                                        tUart1.uResponseTimer = 0;//响应超时计时器清零
                                        tUart1.uComStateflag  = 0x00;//通讯状态设置为响应超时
                                }
                        }
                        if (tUart1.uComStateflag == 0x00)//通讯空闲状态
                        {
                                if ((tUart1.uResponse_flag == 3)&&(p_global_variable.machine_state_flag == FLAG_STATE_FINISH))
                                {
                                        tUart1.uResponse_succeed_Timer++;
                                        if (tUart1.uResponse_succeed_Timer >= 2000)
                                        {
                                                tUart1.uResponse_succeed_Timer = 0;//发送成功计时
                                                tUart1.uResponse_flag = 4;//完成截止数据上传
                                        }
                                }
                        }               
                }
               
                if (tUart1.uComStateflag == 0x00)
                {
                        Uart1_RS485_Receive();    //接收
                }
               
                if ((tUart1.uComStateflag == 0x20)||(tUart1.uComStateflag == 0x21))//接收状态或者接收数据状态
                {
                        tUart1.uRecTimer15++;
                        tUart1.uRecTimer35++;
                        if (tUart1.uRecTimer35 >= 50)
                        {
                                if (tUart1.uComStateflag == 0x20)//若不是目标从机则数据帧结束后直接转到待机状态0x00
                                {
                                        tUart1.uComStateflag = 0x00;
                                }
                                if (tUart1.uComStateflag == 0x21)//若是目标从机则数据帧结束后转到接收数据完成状态0x22
                                {
                                        tUart1.uComStateflag = 0x22;
                                        //tUart1.uCRC_Result = CRC_Result[2];
                                        Upper_Event();//上位机事件
                                }
                                tUart1.uRecTimer15 = 0;
                                tUart1.uRecTimer35 = 0;
                        }
                }
        }                                  
        TIM3->SR&=~(1<<0);//清除中断标志位
}



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2016-1-21
在线时间
30 小时
 楼主| 发表于 2016-1-27 15:42:04 | 显示全部楼层
我跟踪了一下,在中断函数的接收部分的  cRead = USART1->DR;这一句加上断点,打开System Viewer Windows的USART1观察SR寄存器,发现它的第5位RXNE并没有被勾选上。那么它为什么会进去呢?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-1-27 20:28:01 | 显示全部楼层
漆黑丨夜 发表于 2016-1-27 15:42
我跟踪了一下,在中断函数的接收部分的  cRead = USART1->DR;这一句加上断点,打开System Viewer Windows的 ...

肯定有设置.如果没有就不可能运行到这一步.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 07:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表