OpenEdv-开源电子网

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

求USART单线半双工收发程序

[复制链接]

0

主题

0

帖子

0

精华

新手入门

积分
9
金钱
9
注册时间
2020-6-8
在线时间
14 小时
发表于 2016-7-9 19:22:12 | 显示全部楼层 |阅读模式
3金钱
本帖最后由 albertsjc 于 2016-7-9 19:38 编辑

最近在用一款dynamixel舵机,需要用到单线半双工,但是配置时一直出现问题,不知道哪位朋友之前用过usart的单线半双工模式,能指点我一下。
主函数代码
[mw_shl_code=c,true]#include "stm32f10x.h"
#include "lcd.h"
#include "tongxun.h"
#include "delay.h"
#include "key.h"
#include "led.h"

int main(void)
{       
         u8 send_data[6]={0,1,2,3,4,5};
         u8 receive_data[5],len=0;
         u8 key_val=0,i=0;
         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
         LED_Init();
         LED0=0;
         delay_init();
         KEY_Init();
         usart2_init(115200);
         LCD_Init();
         LCD_Clear(WHITE);
         POINT_COLOR=RED;
         LCD_DrawRectangle(0,0,240,320);
         LCD_DrawLine(0,160,240,160);
         LCD_ShowString(30,10,200,16,16,"KEY2:Start Transmition");
         LCD_ShowString(30,40,200,24,24,"Send_Data:");
         LCD_ShowString(30,200,200,24,24,"Receive_Data:");
         USART2->CR2&=~(1<<14);
         USART2->CR2&=~(1<<11);
         USART2->CR3&=~(1<<5);
         USART2->CR3&=~(1<<1);
         PEout(5)=0;
         while(1)
         {
                 key_val=KEY_Scan(0);
                 /********发送数字**********/
                 if(KEY2_PRES==key_val)
                 {
                         for(i=0;i<6;i++)
                                LCD_ShowxNum(30+32*i,80,send_data,3,16,0x80);
                         USART2_Send_Data(send_data,6);
                         LED1=0;
                         LED0=~LED0;
                 }

                 USART2_Receive_Data(receive_data,&len);
                 if(len)                                                //判断是否接受到发送过来的数据
                 {
                                for(i=0;i<len;i++)
                          {
                                                LCD_ShowxNum(30+32*i,240,receive_data,3,16,0x80);
                          }
                                PEout(5)=~PEout(5);
                        LCD_ShowxNum(30,270,len,3,16,0x80);
                 }
         }
}[/mw_shl_code]
下面是收发函数代码


[mw_shl_code=c,true]#include "tongxun.h"
#include "delay.h"

u8 Receive_CNT=0;                        //用于计算接受到的数据
u16 Receive_Data[64];                        //用于储存接收到的数据


void usart2_init(u32 bound)
{
        GPIO_InitTypeDef GPIO_InitStruct;
        USART_InitTypeDef USART_InitStruct;
        NVIC_InitTypeDef NVIC_InitStruct;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);                        //打开GPIO时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);                        //打开USART2时钟
       
        //全双工模式的配置
        //配置TX为复用推挽输出 (push-pull)PA2
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStruct);                                                                               
        //配置RX为浮空输入(floating)                        PA3
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3;
        GPIO_Init(GPIOA,&GPIO_InitStruct);
       
        //配置USART
        USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;                //使能发送接收
        USART_InitStruct.USART_Parity=USART_Parity_No;                                                        //无奇偶校验
        USART_InitStruct.USART_StopBits=USART_StopBits_1;                                                //一位停止位
        USART_InitStruct.USART_WordLength=USART_WordLength_8b;                        //8位字长
        USART_InitStruct.USART_BaudRate=bound;                                                                                //设置波特率
        USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;        //无硬件数据流控制
        USART_Init(USART2,&USART_InitStruct);
       
        //NVIC初始化
        NVIC_InitStruct.NVIC_IRQChannel=USART2_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;
        NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;
        NVIC_Init(&NVIC_InitStruct);
       
        USART_HalfDuplexCmd(USART2,ENABLE);//使能USART2单线半双工模式
       
        USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);                        //开启接受中断
       
        USART_Cmd(USART2,ENABLE);

}

void USART2_IRQHandler(void)                //接收的中断
{
        u16 res;
        if(USART_GetITStatus(USART2,USART_IT_RXNE))
        {
                res = USART_ReceiveData(USART2);
                if(Receive_CNT<64)                //到达数组最大长度后,计数清零
                {
                        Receive_Data[Receive_CNT++]=res;                       
                }
        }
        USART_ClearITPendingBit(USART2,USART_IT_RXNE);
       
}

void USART2_Send_Data(u8 a[],u8 n)                //发送函数
{
        u8 i;

        USART_ClearFlag(USART2,USART_FLAG_TC);
        for(i=0;i<n;i++)
        {
                USART_SendData(USART2,a);
                while(!USART_GetFlagStatus(USART2,USART_FLAG_TC));
        }
        Receive_CNT=0;
}

void USART2_Receive_Data(u8 a[],u8* n)                //接收函数
{
        u8 i;
        delay_ms(30);                //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
        *n=0;
        if(Receive_CNT)
        {
                for(i=0;i<Receive_CNT;i++)
                {
                        a=Receive_Data;
                }
                *n=Receive_CNT;
                Receive_CNT=0;
        }
}

[/mw_shl_code]

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-7-9 20:47:41 | 显示全部楼层
回复

使用道具 举报

0

主题

18

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2016-6-28
在线时间
7 小时
发表于 2016-7-9 21:20:16 | 显示全部楼层
帮忙顶一下,不要沉下去
回复

使用道具 举报

1

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2016-8-19
在线时间
10 小时
发表于 2017-10-4 19:57:36 | 显示全部楼层
老铁,你的半双工选择位呢?
        USART_HalfDuplexCmd(USART1,ENABLE);                //×ü&#207;&#223;°&#235;&#203;&#171;1¤′&#171;ê&#228;ê1&#196;üHDSEL&#214;&#195;1
回复

使用道具 举报

1

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2016-8-19
在线时间
10 小时
发表于 2017-10-4 20:04:35 | 显示全部楼层
//下面5行代码是根据参考手册设置寄存器,注意使能HDSEL放到最后
        USART2->CR3&=0<<5;                //清SCEN
        USART2->CR3&=0<<1;                //清IREN
        USART2->CR2&=0<<11;                //清CLKEN
        USART2->CR2&=0<<14;                //清LINEN
        USART2->CR3|=1<<3;                //使能HDSEL
你的都不在一起
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-20 00:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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