找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 562|回复: 4
打印 上一主题 下一主题
收起左侧

MCU任意IO软件模拟UART串口通讯

[复制链接]
跳转到指定楼层
楼主
soft_uart.c
  1. #include "soft_uart.h"
  2. #include "AIP8F3515.h"

  3. unsigned char soft_uart_tx_buf[SOFT_UART_TX_MAX_BYTE];

  4. unsigned char soft_uart_rx_buf[SOFT_UART_RX_MAX_BYTE];

  5. unsigned char soft_uart_tx_num;

  6. unsigned char soft_send_phase;

  7. unsigned char soft_rx_state_code;

  8. /***************************
  9. 函数名:Soft_Uart_Time_Init
  10. 功能  :定时器初始化
  11. ***************************/
  12. void Soft_Uart_Time_Init(void)
  13. {
  14.         Soft_Uart_Time(SOFT_UART_TIME_ISR);
  15. }

  16. /***************************
  17. 函数名:Soft_Uart_Init
  18. 功能  :UART初始化
  19. ***************************/
  20. void Soft_Uart_Init(void)
  21. {
  22.         SOFT_UART_IO_INIT();
  23.         Soft_Uart_Time_Init();
  24. }

  25. /***************************
  26. 函数名:Soft_Uart_Tx_Nbyte
  27. 功能  :UART发送N字节
  28. str   :字符串
  29. n_byte:需要发送的字节数
  30. 返回值:状态码,检查发送的字节数
  31.                                 是否超过最大设定
  32. ***************************/
  33. unsigned char Soft_Uart_Tx_Nbyte(unsigned char *str,unsigned char n_byte)
  34. {
  35.         unsigned char i;
  36.         if(soft_uart_tx_num != 0)
  37.         {
  38.                 return SOFT_TX_BUSY;
  39.         }
  40.         if(n_byte > SOFT_UART_TX_MAX_BYTE)
  41.         {
  42.                 return SOFT_TX_DATA_COPY_ERR;
  43.         }
  44.         for(i = 0;i < n_byte;i++)
  45.                 soft_uart_tx_buf[i] = *str++;
  46.         
  47.         soft_uart_tx_num  = n_byte;
  48.         soft_send_phase         = SOFT_TX_PHASE_START_SINGLE;
  49.         return SOFT_TX_DATA_COPY_OK;
  50. }

  51. /***************************
  52. 函数名:Soft_Uart_Drive
  53. 功能  :发送、接收,置于
  54.                                 定时器中断内
  55. ***************************/
  56. void Soft_Uart_Drive(void)
  57. {
  58.         static unsigned char tx_bit_num = 0,tx_byte_num = 0,time_count = 0,tx_tem = 0;
  59.         static unsigned char rx_bit_num = 0,rx_byte_num = 0,rx_time_count = 0,rx_tem = 0,rx_phase = 0,rx_xd = 0;
  60.         ++time_count;
  61.         if(time_count >= SET_BIT_TIME_COUNT)
  62.         {//1bit时间
  63.                 time_count = 0;
  64.                 //TX
  65.                 if(soft_uart_tx_num)
  66.                 {                        
  67.                                 if(soft_send_phase == SOFT_TX_PHASE_SEND)
  68.                                 {//开始发送数据
  69.                                         if(tx_tem&0x01)
  70.                                         {
  71.                                                 SOFT_UART_TX = 1;
  72.                                         }
  73.                                         else
  74.                                         {
  75.                                                 SOFT_UART_TX = 0;
  76.                                         }
  77.                                         tx_tem >>= 1;
  78.                                         if(++tx_bit_num >= 8)
  79.                                         {
  80.                                                 tx_bit_num = 0;
  81.                                                 tx_byte_num++;
  82.                                                 soft_send_phase = SOFT_TX_PHASE_STOP_SINGLE;
  83.                                         }
  84.                                 }
  85.                                 else if(soft_send_phase == SOFT_TX_PHASE_START_SINGLE)
  86.                                 {//发送起始码
  87.                                         soft_send_phase = SOFT_TX_PHASE_SEND;
  88.                                         SOFT_UART_TX = 0;
  89.                                         tx_tem = soft_uart_tx_buf[tx_byte_num];
  90.                                 }
  91.                                 else if(soft_send_phase == SOFT_TX_PHASE_STOP_SINGLE)
  92.                                 {//发送停止码
  93.                                         SOFT_UART_TX = 1;//停止码
  94.                                         soft_send_phase = SOFT_TX_PHASE_START_SINGLE;
  95.                                         if(tx_byte_num >= soft_uart_tx_num)
  96.                                         {
  97.                                                 soft_send_phase = SOFT_TX_PHASE_FINISH;
  98.                                         }
  99.                                 }
  100.                                 else if(soft_send_phase == SOFT_TX_PHASE_FINISH)
  101.                                 {//发送一阵数据完成
  102.                                         soft_send_phase = SOFT_TX_PHASE_WAIT_WORK;
  103.                                         soft_uart_tx_num = 0;
  104.                                         tx_byte_num = 0;
  105.                                 }
  106.                 }
  107.         }               
  108.         //RX
  109.         if(rx_phase == SOFT_RX_PHASE_DECODING)
  110.         {
  111.                 if(SOFT_UART_RX)
  112.                         rx_xd++;
  113.                 ++rx_time_count;
  114.                 if(rx_time_count == SET_BIT_TIME_COUNT)
  115.                 {
  116.                         rx_time_count = 0;
  117.                         rx_tem >>= 1;
  118.                         rx_tem  &= 0x7F;//若是右移后最高位自动补0,则不用这一行
  119.                         if(rx_xd >= SET_1_2BIT_TIME_COUNT)
  120.                         {
  121.                                 rx_tem |= 0x80;
  122.                         }
  123.                         rx_xd = 0;
  124.                         if(++rx_bit_num >= 8)
  125.                         {//收满1byte
  126.                                 rx_bit_num = 0;
  127.                                 rx_phase++;
  128.                         }
  129.                 }
  130.         }
  131.         else if(rx_phase == SOFT_RX_PHASE_WAIT_START)
  132.         {
  133.                         if(SOFT_UART_RX == 0)
  134.                         {
  135.                                 rx_time_count++;
  136.                                 if(rx_time_count >= (SET_1_2BIT_TIME_COUNT+1))
  137.                                 {
  138.                                         rx_time_count = 0;
  139.                                         rx_phase++;
  140.                                 }
  141.                         }
  142.                         else
  143.                         {
  144.                                 rx_time_count = 0;
  145.                         }
  146.         }
  147.         else if(rx_phase == SOFT_RX_PHASE_RECV_STOP)
  148.         {
  149.                 if(SOFT_UART_RX)
  150.                 {
  151.                         rx_time_count++;
  152.                 }
  153.                 else
  154.                 {
  155.                         if(rx_time_count >= SET_1_2BIT_TIME_COUNT)
  156.                         {//若是存在干扰,可能接收不到完整的停止信号,判断停止信号若是超过1/2也算通过
  157.                                 rx_time_count = SET_BIT_TIME_COUNT;
  158.                         }
  159.                         else
  160.                         {
  161.                                 rx_time_count = 0;
  162.                         }
  163.                 }
  164.                 if(rx_time_count >= SET_BIT_TIME_COUNT)
  165.                 {//成功收到结束码1bit
  166.                         rx_time_count = 0;
  167.                         rx_phase = SOFT_RX_PHASE_WAIT_START;
  168.                         soft_uart_rx_buf[rx_byte_num] = rx_tem;
  169.                         if(++rx_byte_num >= SOFT_UART_RX_MAX_BYTE)
  170.                         {
  171.                                 rx_byte_num = 0;
  172.                                 soft_rx_state_code = SOFT_RX_RECV_OK;//接收完成
  173.                         }
  174.                 }
  175.         }
  176. }
复制代码

soft_uart.h
  1. #ifndef __SOFT_UART_H__
  2. #define __SOFT_UART_H__
  3. /*软件实现UART******************************************
  4. 波特率                 :4800/9600/14400/19200
  5. 停止位                 :1bit
  6. 奇偶校验         :无
  7. 注意                         :定时器的优先级尽量设高!!!
  8. 使用前定义一定时器名为Soft_Uart_Time,并将步进设置为1us。
  9. 调用Soft_Uart_Init()进行初始化。
  10. 调用Soft_Uart_Drive()在提供时基的定时器中断。
  11. ********************************************************/
  12. extern void Soft_Uart_Time(unsigned char isr_time_us);

  13. //设置用于模拟的IO口
  14. #define SOFT_UART_TX        P50
  15. #define SOFT_UART_RX        P51
  16. //TX设置为推挽输出,RX设置为输入上拉
  17. #define SOFT_UART_IO_INIT()        {P50 = 1;P5IO |= 0X01;P51 = 1;P5IO &= ~0X02;P5PU |= 0X02;}
  18. //设置发送区、接收区大小
  19. #define SOFT_UART_TX_MAX_BYTE 15
  20. #define SOFT_UART_RX_MAX_BYTE 15
  21. //设置通信波特率
  22. #define SOFT_UART_BAUD_RATE                BAUD_RATE_9600

  23. //以下部分无需修改==================================================================================================================
  24. #define BAUD_RATE_4800        4800
  25. #define BAUD_RATE_9600        9600
  26. #define BAUD_RATE_14400        14400
  27. #define BAUD_RATE_19200        19200               

  28. #if(SOFT_UART_BAUD_RATE == BAUD_RATE_4800)
  29.                 #define SOFT_UART_TIME_ISR                        52
  30.                 #define SET_BIT_TIME_COUNT                          4
  31.                 #define SET_1_2BIT_TIME_COUNT                 2
  32. #elif(SOFT_UART_BAUD_RATE == BAUD_RATE_9600)
  33.                 #define SOFT_UART_TIME_ISR                        26
  34.                 #define SET_BIT_TIME_COUNT                          4
  35.                 #define SET_1_2BIT_TIME_COUNT                 2
  36. #elif(SOFT_UART_BAUD_RATE == BAUD_RATE_14400)
  37.                 #define SOFT_UART_TIME_ISR                        23
  38.                 #define SET_BIT_TIME_COUNT                          3
  39.                 #define SET_1_2BIT_TIME_COUNT                 2
  40. #elif(SOFT_UART_BAUD_RATE == BAUD_RATE_19200)
  41.                 #define SOFT_UART_TIME_ISR                        26
  42.                 #define SET_BIT_TIME_COUNT                          2
  43.                 #define SET_1_2BIT_TIME_COUNT                 1
  44. #endif

  45. enum SORT_TX_STATE{
  46.         SOFT_TX_DATA_COPY_OK,        //拷贝数据成功
  47.         SOFT_TX_DATA_COPY_ERR,        //拷贝发送的字节数超过最大设置
  48.         SOFT_TX_BUSY,                        //当前有未发送的数据
  49. };

  50. enum SOFT_RX_PHASE{
  51.         SOFT_RX_PHASE_WAIT_START,//等待接收
  52.         SOFT_RX_PHASE_DECODING,         //接收中
  53.         SOFT_RX_PHASE_RECV_STOP, //接收停止信号
  54. };

  55. enum SOFT_TX_PHASE{
  56.         SOFT_TX_PHASE_WAIT_WORK,        //等待发送
  57.         SOFT_TX_PHASE_START_SINGLE,        //发送起始信号
  58.         SOFT_TX_PHASE_SEND,                        //发送数据
  59.         SOFT_TX_PHASE_STOP_SINGLE,        //发送停止信号
  60.         SOFT_TX_PHASE_FINISH,                //发送SOFT_UART_TX_MAX_BYTE字节完成
  61. };

  62. enum SOFT_RX_STATE_CODE{
  63.         SOFT_RX_DECODING,//接收中
  64.         SOFT_RX_RECV_OK         //接收SOFT_UART_RX_MAX_BYTE字节,1帧数据
  65. };


  66. void Soft_Uart_Io_Init(void);
  67. void Soft_Uart_Time_Init(void);
  68. void Soft_Uart_Init(void);
  69. unsigned char Soft_Uart_Tx_Nbyte(unsigned char *str,unsigned char n_byte);
  70. void Soft_Uart_Drive(void);

  71. #endif
复制代码


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:654797 发表于 2024-7-26 18:43 | 只看该作者
AIP8F3515.H是STC芯片的头文件吗
回复

使用道具 举报

板凳
ID:1064915 发表于 2024-7-27 08:54 | 只看该作者
中微爱芯推出的8051内核触摸型MCU,其ROM从8KB到64KB可选,可满足不同复杂程度的方案需求。提供多触摸通道及ADC,并集成LED、LCD驱动。触摸MCU包含电容型AiP8F32XX系列和无电容型AiP8F35XX系列。

电容型AiP8F32XX系列-AiP8F3208 AiP8F3216/E AiP8F3264

AiP8F3216是一款触摸型8051内核MCU,内置16KB FLASH ROM、128B EEPROM、1KB XRAM、256B IRAM、内部集成Timer0/1/2/5、UART1/2、SPI、WDT、I2C、WT、LCD、TOUCH,OPA和12bit-ADC。可提供SOP20/SSOP20/SOP28/SSOP28封装。

无电容型AiP8F35XX系列- AiP8F3515 AiP8F3516 AiP8F3532

AiP8F3532是一款触摸型8051内核MCU,内置32KB FLASH ROM、1KB XRAM、256B IRAM,内部集成Timer0/1/2/5、WT、WDT、CRC、UART1/2、SPI、I2C、LCD和TOUCH、12bit-ADC、LVD、LVR。可提供SOP32/SOP28/SOP20 /LQFP32封装。具有高灵敏度、节省硬件成本等特点。
回复

使用道具 举报

地板
ID:592337 发表于 2024-7-30 11:00 | 只看该作者
vscos 发表于 2024-7-26 18:43
AIP8F3515.H是STC芯片的头文件吗

替换成自己使用芯片的.h就好
回复

使用道具 举报

5#
ID:90212 发表于 2024-7-31 20:01 | 只看该作者
楼主精神可嘉!很多范例都在stcisp的工具里面,很多人守着金饭碗讨饭!玩51单片机把stcisp工具吃透就是高手了:




回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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