0xxx STM8S串口通讯协议のUART

STM8S串口通讯协议のUART的实现

理解STM8S的UART关于理解以下几个概念:

  • 协议收发格式

    • 起始位(start bit)
    • 数据位 (a date word)
    • 结束位(stop bit)
    • 奇偶校验位 (parity)
  • 帧(frame)

    • 以起始位 + 数据位 + 结束为 + 奇偶校验位 构成的一次数据收发被称为帧,同时也是UART传输的基本单位
    • UART时序如图,截自STM8S参考手册:
      UART数据帧格式
  • 状态寄存器(status register)

    • 可以将寄存器中的每一个bit看作一支flag,通过读状态寄存器某个bit可以监视数据的收发状态,决定是否该继续收发
      如在接收数据时,数据还没有从RSR(Receive Shift Register)中转移到RDR(Receive Date Register),那么此时就不应该读数据,因为被读的数据将存放在RDR中
      此时就可以用 while(!(UART1_SR && (1<<5))); 来监视数据是否已经转移完成,如完成,则仅需开始进行读操作
  • 数据寄存器(Date Register)

    • 如图,截自STM8S参考手册:
      Date Register
      可见数据寄存器并非简单的指一个寄存器,而是由四个寄存器组成的寄存器组(这就是为什么UART能做到全双工通讯的原因,接收和发送由不同的寄存器分别处理)
      以接收和发送数据为目的划分,数据帧在寄存器组中有以下流向关系:
      接收数据: 数据帧接收 -> RSR -> RDR
      发送数据:数据帧发送 -> TDR -> TSR
  • 16位波特率寄存器(Baud Rate Registers)

    • 波特率寄存器由两个8位寄存器UART_BRR2和UART_BRR1构成(UART_BRR2应先与UART_BRR1被赋值,因为当UART_BRR1被写入一个值,UART的通讯波特率就会被更新;但在传输过程中这是不被允许的)红字信息来源STM8S参考手册
    • UART_BRR2和UART_BRR1的值根据所需波特率求得,如下图:
      在这里插入图片描述

代码及实现思路O(∩_∩)O

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */
#include <stm8s003f3.h>

// 功能:输入一个字符,将字符+1,然后输入

// 思路
// 1. 时钟初始化
// 2. UART初始化 - 波特率 - 数据位 - 基偶校验位 - 结束位
// 3. 接收数据函数 - 接收的主体是STM8S
// 4. 发送数据函数 - 发送的主体是STM8S
// 5. 在主函数写实现逻辑
// ATTENTION: 通过UART_SR(status register)的bit来monitor发送/接收是否完成(注意查看参考手册是否需要清0)

unsigned char UART_RX(void);
void UART_TX(unsigned char);
void UART_Init(void);

main()
{
  // 初始化时钟
  // 不知这种直接写寄存器有没有用,STM8S默认时钟频率为2Mhz
  CLK_CKDIVR = 0x00; // set clock to 16Mhz
  CLK_PCKENR1 = 0xFF; // enable periperals
  
  UART_Init();
  
	while (1)
  {
    // 实参,发送到屏幕的数据
    // 要传给UART_TX函数
    unsigned char ch = 0;
    
    // 功能:STM8s通过UART将从键盘输入的字符+1,然后再返回到屏幕
    // 实现:
    // 0. 开始
    // 1. 处理数据前,想判断一下在RSR中的数据是否已经被转移
    //    到RDR。理由是防止数据还没转移到RDR就被新输入的数据刷新掉
    // 2. 先调用UART_RX,通过返回值,查看从键盘上输入的
    //    存放在UART_DR的字符
    // 3. 将UART_RX的返回值赋值给实参ch
    // 4. 将ch++
    // 5. 将自增后的ch作为形参,传给UART_TX函数
    // 6. 结束
    
    // 实现
    if(UART1_SR && (1<<5))
    {
      ch = UART_RX();
      ch++;
      UART_TX(ch);
    }
  
  }
}


// @brief   接收函数
// @retval  unsigned char
// @param   null
unsigned char UART_RX(void)
{
  // 等待数据从RSR(Receive Shift Register)转移到RDR(Receive Date Register)
  // 查看参考手册UART_SR哪一位用来查看该状态
  // Bit5为RXNE位,该为置1,则表示数据已经从RSR -> RDR,则需要读UART_DR中的数据(返回该寄存器值即可)
  while(!(UART1_SR && (1<<5)));
  return UART1_DR;
}

// @brief   发送函数
// @retval  null
// @param   发送UART_DR中的数据(即TDR中的数据)
void UART_TX(unsigned char val){
  // 数据发送,将形参val赋值给UART1_DR
  UART1_DR = val;
  // 参考RX函数中的写法
  // 等待数据从TDR转移到TSR中
  // Bit7为TXE位,该位置1,则表示数据已从TDR -> TSR
  // 可以进行数据发送
  //while(!(UART1_SR && (1<<7)));
  // 等待数据发送完成
  // Bit6为bit complete位,置1表示数据已发送完毕!!!!!!
  while(!((UART1_SR && (1<<6))));
}

// @brief   UART1初始化函数
void UART_Init(void)
{
  // 求波特率具体方式查看芯片参考手册
  UART1_BRR2 = 0x03;
  UART1_BRR1 = 0x68; // 9600 baud,先写BBR2寄存器
  UART1_CR3 &= ~((1<<4) | (1<<5)); // 1 stop bit
  UART1_CR1 &= ~((1<<4)); // 8 bits Date, no parity
  // 全部设置完后,使能!!!
  UART1_CR2 |= (1<<2) | (1<<3); // set receiver and transmitter enable without interrupt
  
}

结果

实现预期效果,且收发正常
代码运行结果

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值