打印
[STM32F1]

模拟UART串口通信

[复制链接]
178|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
beacherblack|  楼主 | 2024-2-27 23:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
UART即通用异步收发器,是一种串行通信方式。数据在传输过程中是通过一位一位地进行传输来实现通信的,串行通信方式具有传输线少,成本底等优点,缺点是速度慢。串行通信分为两种类型:同步通信方式和异步通信方式。


每一个字符的传输靠起始位来同步,字符的前面一位是起始位,用下降沿通知收方开始传输,紧接着起始位之后的是数据位,传输时低位在前高位在后,字符本身由5~8位数据位组成。

UART的帧格式如图:
UART的帧格式包括线路空闲状态(idle,高电平)、起始位(start bit,低电平)、5~8位数据位(data bits)、校验位(parity bit,可选)和停止位(stop bit,位数可为1、1.5、2位)。

UART模拟原理

方案1:只打印不接收

#define  VCOM_BOUND     115200
#define  VCOM_PORT      GPIOA
#define  VCOM_PIN_LOW   VCOM_PORT->BRR  = VCOM_PIN


#define  BSP_REG_DWT_CR                           (*(volatile unsigned int *)0xE0001000)   //DWT控制寄存器
#define  BSP_REG_DBGMCU_CR                        (*(volatile unsigned int *)0xE0042004)


#define  DEF_BIT_24                               0x01000000u
#define  BSP_BIT_DWT_CR_CYCCNTENA                 DEF_BIT_00
inline void dwt_start(void)
BSP_REG_DEM_CR     |= (unsigned int)BSP_BIT_DEM_CR_TRCENA;
    BSP_REG_DWT_CR     |= (unsigned int)BSP_BIT_DWT_CR_CYCCNTENA;    //开启CYCCNT
inline void dwt_stop(void)
BSP_REG_DWT_CR = 0;
void vcom_pin_init(void)
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin   = VCOM_PIN;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_SetBits(VCOM_PORT,VCOM_PIN);
}


{
int dat[8];
volatile uint32_t time_stamp;

    bit_width = 1000000*sys_clk/VCOM_BOUND;
    {
            dat = 1;
            dat = 0;
    }
    enter_critical();//以下代码进行临界保护,防止被中断打断造成发送误码
    VCOM_PIN_LOW; //发送起始位
while(BSP_REG_DWT_CYCCNT < (time_stamp+bit_width));
{
   VCOM_PIN_HIGH;
   VCOM_PIN_LOW;
  while(BSP_REG_DWT_CYCCNT < (time_stamp+bit_width)); //发8bit 数据位
VCOM_PIN_HIGH;
while(BSP_REG_DWT_CYCCNT < (time_stamp+bit_width));     //发停止位
exit_critical();
void vcom_printf(const char *fmt, ...)
    char buf[0x80];
    va_list ap;
    va_start(ap, fmt);
    va_end(ap);

while(buf)
  vcom_put_char(buf);
}
方案2:半双工UART

/**
* 波特率:9600    1-8-N
* RXD : PB14
* Demo功能: 接收11个数据,然后把接收到的数据发送出去
#define OI_TXD PCout(13)
#define BuadRate_9600 100


u8 USART_buf[11];  //接收缓冲区


COM_START_BIT,
COM_D1_BIT,
COM_D3_BIT,
COM_D5_BIT,
COM_D7_BIT,
};


u8 recvData = 0;


{
OI_TXD = 0;  
for(i = 0; i < 8; i++)
  if(Data&0x01)
  else
  delay_us(BuadRate_9600);
}
delay_us(BuadRate_9600);
void USART_Send(u8 *buf, u8 len)
u8 t;
{
}
void IOConfig(void)
GPIO_InitTypeDef  GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStruct;
//SoftWare Serial TXD
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //推挽输出
GPIO_Init(GPIOC, &GPIO_InitStructure);      
//SoftWare Serial RXD
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);  

EXTI_InitStruct.EXTI_Line = EXTI_Line14;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发中断
EXTI_Init(&EXTI_InitStruct);


NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;  
}

{
NVIC_InitTypeDef NVIC_InitStructure;

//定时器TIM4初始化
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
TIM_ClearITPendingBit(TIM4, TIM_FLAG_Update);
//中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
}


{  
delay_init();
TIM4_Int_Init(107, 71);  //1M计数频率

{
  {
   USART_Send(USART_buf,11);
}
void EXTI15_10_IRQHandler(void)
if(EXTI_GetFlagStatus(EXTI_Line14) != RESET)
  if(OI_RXD == 0)
   if(recvStat == COM_STOP_BIT)
    recvStat = COM_START_BIT;
   }
  EXTI_ClearITPendingBit(EXTI_Line14);
}


{  
{
  recvStat++;
  {
   USART_buf[len++] = recvData;
  }
  {
  }else{
  }
}

使用特权

评论回复
沙发
xuanhuanzi| | 2024-2-29 22:41 | 只看该作者
主要是定时器要准。

使用特权

评论回复
板凳
xuanhuanzi| | 2024-2-29 22:41 | 只看该作者
通过定时器来确定波特率。

使用特权

评论回复
地板
Charlene沙| | 2024-2-29 23:03 | 只看该作者
这不错啊,现在很多都不用模拟串口了,其实是因为现在的单片机串口比较多了

使用特权

评论回复
5
天灵灵地灵灵| | 2024-2-29 23:13 | 只看该作者
通过导入信号可以实现自动波特率。

使用特权

评论回复
6
天灵灵地灵灵| | 2024-2-29 23:13 | 只看该作者
模拟的就是在时钟下,按照一定的波特率发送。

使用特权

评论回复
7
问天少年| | 2024-3-11 13:46 | 只看该作者
模拟UART很通用,但是这个感觉没必要模拟

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

1059

帖子

1

粉丝