zhe最近在搞一个IO口模拟LIN的代码,其中包括IO口模拟UART的部分,就记录一下,希望对像我们这样的初学者能有所帮助。

1. 串口协议

串口的特点:全双工,串行,异步

串口协议(我这里选用最常见的一种):一个起始位,八个字节长度,无奇偶校验,一个停止位,一帧包括十个比特。图的话就不上传了,这个大家应该都很清楚。

2. 如何模拟

2.1 模拟发送

发送倒是很简单,直接按协议发就完事,只需要注意波特率的设置,我这里选用9600,每个比特传输时间为104us,这个怎么算其实很简单,用1/9600转换成us就行了,我这里发的话就没有用到定时器,直接使用滴答计时器延时函数。代码如下:

void uart1_putchar(uint8_t val)
{uint8_t i = 0;UART_TX_LOW() ;//拉低发送引脚,起始位delay_us((1000000*1)/LIN_BPS);for(;i<8;i++){if(val&0x01){UART_TX_HIGH();delay_us((1000000*1)/LIN_BPS);}else{UART_TX_LOW();delay_us((1000000*1)/LIN_BPS);}val>>=1;}UART_TX_HIGH();//拉高发送引脚,停止位delay_us((1000000*1)/LIN_BPS);
}

2.2 模拟接收

接收的话稍微复杂一点,需要用到外部中断和定时器中断,我们把定时器周期调为52us,外部中断为下降沿中断,逻辑为:外部触发下降沿中断,中断函数中如果读取引脚电平为0且为起始位的话,启动定时器中断,关闭外部中断,在第一次进定时器中断时,多次读取对应电平,如果均为低电平,则表示起始位正确,然后偶数次进中断不做处理,奇数次进中断多次读取电平值,取其多数值,最后index为19时表明一个字节接收完毕,启动外部中断,关闭定时器中断。代码如下:

void PORTE_IRQHandler(void)//外部中断
{if((PTE->PDIR & (1<<16))==0x00){delay_us(10);if(UART_RX_Value() == 0){if(RBtIdx == 0){INT_SYS_DisableIRQ(PORTE_IRQn);//使能外部中断LPIT0->TMR[1].TCTRL = 0x00000001;//使能定时器中断}}}PORTE->ISFR |= 0x4000;//清楚中断标志
}
void LPIT0_Ch1_IRQHandler (void){LPIT0->MSR |= LPIT_MSR_TIF1_MASK;//清楚中断问题RBtIdx++;if(RBtIdx == 1){if(FourTimesDetectStart() == 0){RBtIdx = 0;return ;}}else if(RBtIdx == 19){LPIT0->TMR[1].TCTRL = 0x00000000;INT_SYS_EnableIRQ(PORTE_IRQn);RBtIdx = 0;}else if(RBtIdx % 2){RxData>>=1;if(FourTimesDetectData()){RxData|=0x80;}}}

3 附加引脚初始化,定时器初始化,和延时函数代码初始化

我使用的IO引脚是PB4(out)和PD16(in)

 PCC->PCCn[PCC_PORTB_INDEX] |= PCC_PCCn_CGC_MASK;PTB->PDDR |= 1<<4;PORTB->PCR[4] =  0x00000100;PTB-> PSOR |= 1<<4;PCC->PCCn[PCC_PORTE_INDEX] |= PCC_PCCn_CGC_MASK;PTE->PDDR &= ~(1<<16);PORTE->PCR[16] = PORT_PCR_MUX(1)|PORT_PCR_IRQC(0x0a)|PORT_PCR_PS(1)|PORT_PCR_PE(1);//上拉,下降沿中断S32_NVIC_EnableIRQ(PORTE_IRQn,9);

定时器使用的是IT0的第一个通道

 PCC->PCCn[PCC_LPIT_INDEX] = PCC_PCCn_PCS(6);    PCC->PCCn[PCC_LPIT_INDEX] |= PCC_PCCn_CGC_MASK; /* Enable clk to LPIT0 regs */LPIT0->MCR = 0x00000001;    LPIT0->MIER = 0x00000001;  LPIT0->TMR[1].TVAL = 2080;    /* Chan 0 Timeout period: 0.04M clocks */            //52us

延时函数初始化

void s32_systick_init(void){S32_SysTick->CSR = S32_SysTick_CSR_ENABLE(0);fac_us = 80000000 / 1000000;S32_SysTick->RVR = 0xFFFFFF; //重装载寄存器S32_SysTick->CVR = 0; //当前计数S32_SysTick->CSR = 0; //控制寄存器S32_SysTick->CSR |= S32_SysTick_CSR_TICKINT(1u)|S32_SysTick_CSR_ENABLE(1)|S32_SysTick_CSR_CLKSOURCE(1u);
}void delay_us(uint32t nus){uint32_t ticks;uint32_t told,tnow,tcnt=0;uint32_t reload=S32_SysTick->RVR;             //LOAD的值ticks=nus*fac_us;                      //需要的节拍数told= S32_SysTick->CVR ;                    //刚进入时的计数器值while(1){tnow= S32_SysTick->CVR ;if(tnow!=told){if(tnow<told)tcnt+=told-tnow;  //这里注意一下SYSTICK是一个递减的计数器就可以了.else tcnt+=reload-tnow+told;told=tnow;if(tcnt>=ticks)break;            //时间超过/等于要延迟的时间,则退出.}}
}

4.总结

IO口模拟UART的收发按照UART的时序来即可,虽然看起来很简单,但是动手的时候还是会有一些问题的,踏踏实实做好每一步,不要眼高手低。

基于s32k146的IO口模拟串口相关推荐

  1. 单片机IO口模拟串口程序(发送+接收

    单片机IO口模拟串口程序(发送+接收)[转] qcmc 发表于 - 2011-6-23 0:42:00 前一阵一直在做单片机的程序,由于串口不够,需要用IO口来模拟出一个串口.经过若干曲折并参考了一些 ...

  2. STM8学习笔记----普通IO口模拟串口功能

    串口在产品应用中很常见,但是单片机的默认带的串口往往比较少,有时候就会出现串口不够用,所以就想着能不能用普通IO口模拟串口来实现串口的功能. 要模拟串口首先要清楚串口数据传输过程中的原理. 常用的串口 ...

  3. 串口发送程序linux,单片机IO口模拟串口程序(发送+接收

    前一阵一直在做单片机的程序,由于串口不够,需要用IO口来模拟出一个串口.经过若干曲折并参考了一些现有的资料,基本上完成了.现在将完整的测试程序,以及其中一些需要总结的部分贴出来. 程序硬件平台:11. ...

  4. STM32 IO口模拟串口通讯

    转自:http://ziye334.blog.163.com/blog/static/224306191201452833850647 前阵子,调项目时需要用到低波特率串口通讯(300的波特率),才发 ...

  5. 20120726-分析解决“STM8L101单片机IO口模拟串口通讯发生的奇怪现象”

    近日因工作关系,需要用STM8L101F3P6这款单片机用IO口模拟串行通讯,波特率2400bps,前辈同事已经写完了程序,我需要拿来研究一下该款MCU的低功耗的情况,而在调试的过程中,发现1个奇怪的 ...

  6. 芯圣SQ013单片机IO口模拟串口 延时法

    因为懒,许久未来更新,不过学习还是没有停止.今天我们介绍用芯圣SQ013模拟串口. 串口通讯概述 我们常用的串口通讯协议 为1个起始位+8个数据位+1位结束位.起始位为低电平,结束位高电平.一般我们常 ...

  7. 普通io口模拟串口通信

    之前公司在做项目的时候需要用到多串口,板载串口资源不足,就在网上找相关内容,结合自己的理解做出虚拟串口. 模拟串口需要用到两个普通io引脚,一个定时器. /** *软件串口的实现(IO模拟串口) * ...

  8. io口模拟串口 1602显示数据位内容[转]

    一个项目的一部分内容,让初学者模拟着做一下,还是很有用处的. 这样的程序可以实现一个51单片机有两个串口 #include<regx52.h> sbit BT_SND =P1^1; sbi ...

  9. io口模拟spi,stm32f103与MS5611基于spi总线的温度压力高度数据读取

    以下文件为源文件 /** -----------------------MS5611驱动 && IO口模拟SPI驱动------------------------- ******** ...

最新文章

  1. MySQL查询优化-explain
  2. 新手玩家一定要学会配枪,使命召唤手游,对枪械是非常专业的
  3. 迷宫游戏c语言代码讲解,迷宫游戏C语言代码讲解.doc
  4. 要做PPT,一直找不到资源?
  5. restfull知识点
  6. python代码模板_python 代码模板
  7. 160 - 54 eKH
  8. 友盟分享小程序_在线学习应用“小打卡”小程序分享
  9. 自助式BI和传统BI有什么区别
  10. pl/sql developer 快捷操作: 显示不可见字符 显示历史sql语句 拷贝整个sql窗口的语句至新的sql窗口...
  11. 总结一下自己脑海里的JavaScript吧(一)--DOM模型
  12. Vscode编辑器配置
  13. jad反编译成java_反编译工具jad的使用(将*.class文件变成*.java文件,附带jad.zip包)[转]...
  14. 使用FileTypesMan修复office关联图标
  15. 【一起学Rust | 进阶篇 | Service Manager库】Rust专用跨平台服务管理库
  16. 监控系统选型,这篇不可不读!
  17. 《春·蜂》processing下的动画技术交互应用
  18. 数据结构—约瑟夫环问题(C语言版)
  19. C语言中的fgets函数
  20. 查看ubuntu服务器防火墙配置文件,Ubuntu Server服务器防火墙ufw开启及配置方法 | 坐倚北风...

热门文章

  1. 2022年诺贝尔物理学奖的科学内涵辨识
  2. 行人跟踪之身份识别(三)
  3. CSP报错运行错误?
  4. OSChina 周一乱弹 ——有2个小混蛋大晚上……
  5. 2020强网杯部分题目复现
  6. 实战python网络爬虫豆瓣_三分钟教会你利用Python爬虫实现豆瓣电影采集(实战篇)...
  7. 人和计算机下棋该应用属于 a,两个人下棋的过程,叫“对局”“对弈”,也叫()A. 手谈B.作战 - 作业在线问答...
  8. RealView Development Suite 4.0 Professional安装
  9. 编程及C/C++初学者 FAQ
  10. idea maven子项目图标右下角没有小蓝方块