单片机GPIO中断+定时器 实现模拟串口接收

news2024/11/20 18:41:49

单片机GPIO中断+定时器 实现模拟串口接收

  • 解决思路
  • 代码示例

解决思路

串口波特率9600bps,每个bit约为1000000us/9600=104.16us; 定时器第一次定时时间设为52us即半个bit的时间,其目的是偏移半个bit时间,之后的每104us采样并读取1bit数据。使得采样点搞好在每位数据脉宽的中间点。

在这里插入图片描述

代码示例

  • 串口波特率9600bps,每个bit约为1000000us/9600=104.16us;
  • 定时器开始时定时时间设为52us,即半个bit的时间,并关闭定时器;
  • GPIO设为中断模式下降沿触发,测到第一个下降沿(即串口的S信号),定时器设定52us开启定时,关闭GPIO中断,并设置状态为E_IO_UART_STATE_IDLE。
  • 定时器触发52us定时E_IO_UART_STATE_IDLE状态改为E_IO_UART_STATE_START。定时器设置为104us,之后每触发一次104us定时中断读取1bit串口数据,直到8bits数据全部解析完成,重置为下次接收状态;
#if TCFG_SENSOR_CO_MODULE_EN
struct io_uart_t {
    uint8_t state;
    uint8_t index;
    uint8_t _data;
    uint8_t ready;
    uint8_t rxlen;
    uint8_t _recv[7];
};
static struct io_uart_t io_uart;
void timer1_init(void);
#endif

#if TCFG_SENSOR_CO_MODULE_EN
enum {
    E_IO_UART_STATE_IDLE=0,     // 空闲状态
    E_IO_UART_STATE_START,      // 开始接收数据
    E_IO_UART_STATE_END,        // 数据接收完成
};

#define TIMER1_TICK_HEAD         60  // 52us    104/2=52us  半个开始信号的时间
#define TIMER1_TICK_DATA         139 // 104us   1000000/9600=104.16us 一个数据位的时间
void timer1_init(void)
{
    SCCM1 |= RCC_SCCM1_TIMER1;
    TMOD  |=Bit5_En ;
    TMOD  &=Bit4_Dis;

    TH1=256-TIMER1_TICK_HEAD;        
    TL1=256-TIMER1_TICK_HEAD; 
   
    TR1=0;        //定时器1使能运行
    EAL=1;        //总中断打开
    ET1=1;        //定时器1中断打开

    IRQ_Vic_Set(INT_TIMER1, pritrity_level_fourth);     // 设置定时器优先级最高
    // IRQ_Enable(IT_ALL);
}

void Interrupt_GPIO0 (void) interrupt 20    //GPIO0中断服务程序
{
    // P07=~P07;
    if(IO_GetIntState(GPIO_P0,GPIO_Pin_6))
    {
        // P07=~P07;    // for test

        // TODO: 检测到第一个下降沿:S信号,设置定时器初值52us,启动定时器,关闭外部中断
        TH1=256-TIMER1_TICK_HEAD;  
        TL1=256-TIMER1_TICK_HEAD;
        TR1=1;

        io_uart.state = E_IO_UART_STATE_IDLE;
        IO_INT_Disable(  GPIO_P0,GPIO_Pin_6);
        // IRQ_Disable(IT_GPIO0);
        IO_CleanIntState(GPIO_P0,GPIO_Pin_6);
    }
    P0_INT_REG = 0xff;
}

/*中断方式*/
void Interrupt_TIMRT1 (void) interrupt 3    //TIMRT1中断服务程序
{	
    uint8_t checksum = 0;

	TF1 = 1; //清标志
	// TIMER01_SetPeriod(TIMER1,TIMERMODE_VALUE,TIMER1_TICK);
	// P07=~P07;   // for test

    if (io_uart.state == E_IO_UART_STATE_START) {
        P07=~P07; // FOR TEST
        io_uart._data = io_uart._data >> 1; // 数据右移一位
        if (P06 == 1) { 
            io_uart._data |= 0x80;    // 如读取到的串口GPIO电平为高,高位位或运算
        }

        io_uart.index++;
        if (io_uart.index == 8) {
            io_uart.state = E_IO_UART_STATE_END;
            IO_INT_Enable(  GPIO_P0,GPIO_Pin_6);
            // IRQ_Enable(IT_GPIO0);
            TR1=0;

            if (io_uart._data == 0xAA) {
                io_uart.rxlen = 0;
                memset(io_uart._recv, 0, sizeof(io_uart._recv));
            }
            io_uart._recv[io_uart.rxlen] = io_uart._data;
            io_uart.rxlen++;
            if (io_uart.rxlen == 7)
            {
                checksum = (uint8_t)(io_uart._recv[1]+io_uart._recv[2]+io_uart._recv[3]+io_uart._recv[4]);
                if (checksum == io_uart._recv[5]) {
                    // TODO: 和校验正确
                    // P07=~P07;   // for test
                    _this->sensor_co.covol = (uint16_t)(io_uart._recv[1]<<8 | io_uart._recv[2]);
                    io_uart.ready = 1;
                }
            }
        }
    }
    
    if (io_uart.state == E_IO_UART_STATE_IDLE) {
        io_uart.state = E_IO_UART_STATE_START;
        io_uart.index = 0;
        io_uart._data = 0;

        TH1=256-TIMER1_TICK_DATA;        
        TL1=256-TIMER1_TICK_DATA;
    }
}
#endif

void main ()
{
#if TCFG_SENSOR_CO_MODULE_EN
    timer1_init();
    
    RCC_Sccm1_ClockCmd(RCC_SCCM1_GPIO,ENABLE);

    IO_FUN_Config(GPIO_P0,GPIO_Pin_7,GPIO_FUNCTION_DF0); //配置引脚为GPIO功能    	
    IO_OUT_Enable(GPIO_P0, GPIO_Pin_7);
    IO_PU_Enable(GPIO_P0, GPIO_Pin_7);

    // TOODO: 模拟串口接收
	/*只有P0和P1口可以配置为电平触发,其他端口只能配置为沿触发*/
	IO_FUN_Config( 	GPIO_P0,GPIO_Pin_6,GPIO_FUNCTION_DF0); //配置引脚为GPIO功能
    IO_PU_Enable(   GPIO_P0,GPIO_Pin_6);
	IO_INPUT_Enable(GPIO_P0,GPIO_Pin_6);            //配置引脚为GPIO输入模式
	IO_INT_Config(  GPIO_P0,GPIO_Pin_6, falling);	//需要外接接下拉电阻	
	IO_INT_Enable(  GPIO_P0,GPIO_Pin_6);
	IRQ_Enable(IT_GPIO0);
#endif

while(1)
{
	...
}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2244189.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

近几年新笔记本重装系统方法及一些注意事项

新笔记本怎么重装系统&#xff1f; 近几年的新笔记本默认开启了raid on模式或vmd选项&#xff0c;安装过程中会遇到问题&#xff0c;新笔记本电脑重装自带的系统建议采用u盘方式安装&#xff0c;默认新笔记本有bitlocker加密机制&#xff0c;如果采用一键重装系统或硬盘方式安装…

【支持向量机(SVM)】:算法原理及核函数

文章目录 1 SVM算法原理1.1 目标函数确定1.2 约束条件优化问题转换1.3 对偶问题转换1.4 确定超平面1.5 计算举例1.6 SVM原理小节 2 SVM核函数2.1 核函数的作用2.2 核函数分类2.3 高斯核函数2.3 高斯核函数API2.4 超参数 γ \gamma γ 1 SVM算法原理 1.1 目标函数确定 SVM思想…

自动驾驶系列—告别眩光烦恼:智能大灯如何守护夜间行车安全

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

无插件H5播放器EasyPlayer.js RTSP播放器chrome/edge等浏览器如何使用独立显卡

随着互联网的快速发展和视频内容的日益丰富&#xff0c;HTML5视频播放器已成为网页视频播放的主流技术。EasyPlayer.js播放器视频播放技术不仅支持多种浏览器和设备&#xff0c;还提供了丰富的功能和更好的用户体验。 那么chrome/edge等浏览器如何使用独立显卡&#xff1f; 在…

@Autowired 和 @Resource思考(注入redisTemplate时发现一些奇怪的现象)

1. 前置知识 Configuration public class RedisConfig {Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template new RedisTemplate<>();template.setConnectionFactory(facto…

STM32低功耗设计NFC与无线距离感应智能钥匙扣-分享

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 智能钥匙扣作为一种小巧而实用的智能设备&#xff0c;凭借其便携性…

微服务day09

DSL查询 快速入门 GET /items/_search {"query": {"match_all": {}} } 叶子查询 GET /items/_search {"query": {"match_all": {}} }GET /items/_search {"query": {"multi_match": {"query": "脱…

Golang语言整合jwt+gin框架实现token

1.下载jwt go get -u github.com/dgrijalva/jwt-go2.新建生成token和解析token文件 2.1 新建common文件夹和jwtConfig文件夹 新建jwtconfig.go文件 2.2 jwtconfig.go文件代码 /* Time : 2021/8/2 下午3:03 Author : mrxuexi File : main Software: GoLand */ package jwtC…

Orcad 输出有链接属性的PDF

安装adobe pdf安装Ghostscript修改C:\Cadence\SPB_16.6\tools\capture\tclscripts\capUtils\capPdfUtil.tcl ​ 设置默认打印机为 Adobe PDF ​ 将Ghostscript的路径修改正确 打开cadence Orcad &#xff0c;accessories->candece Tcl/Tk Utilities-> Utilities->PD…

Java读取WPS excel.xlsx嵌入图片

1. 背景&原因 经常有读取Excel文件的需求&#xff0c;开发者大多使用apache poi或者基于此的工具进行excel内容读取&#xff0c;前不久遇到了一个需求&#xff0c;读取每一行内容&#xff0c;但每一行都包含图片文件&#xff0c;发现无法通过已封装的工具读取excel的图片内…

Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别

Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别 keyword 与 text 区别term 查询match 查询match_phrase 查询match_phrase_prefix 查询写在最后 在讲述 es 查询时 term、match、match_phrase、match_phrase_prefix 的区别之前&#xff0c;先来了…

ERROR TypeError: AutoImport is not a function

TypeError: AutoImport is not a function 原因&#xff1a;unplugin-auto-import 插件版本问题 Vue3基于Webpack&#xff0c;在vue.config.js中配置 当unplugin-vue-components版本小于0.26.0时&#xff0c;使用以下写法 const { defineConfig } require("vue/cli-se…

iOS 18 导航栏插入动画会导致背景短暂变白的解决

问题现象 在最新的 iOS 18 系统中,如果我们执行导航栏的插入动画,可能会造成导航栏背景短暂地变为白色: 如上图所示:我们分别向主视图和 Sheet 弹出视图的导航栏插入了消息,并应用了动画效果。可以看到,前者的导航栏背景会在消息插入那一霎那“变白”,而后者则没有任何…

PHP屏蔽海外IP的访问页面(源代码实例)

PHP屏蔽海外IP的访问页面&#xff08;源代码实例&#xff09;&#xff0c;页面禁用境外IP地址访问 <?php/*** 屏蔽海外ip访问* 使用ip2long函数得到ip转为整数的值&#xff0c;判断值是否在任一一个区间中* 以下是所有国内ip段* 调用方法&#xff1a;IschinaIp($ALLIPS)* …

SpringBoot 增量部署发布(第2版)

一、背景介绍 书接上一篇《SpringBoot 增量部署发布_springboot增量部署-CSDN博客》&#xff0c;上一篇内容实现了将静态资源与jar分离&#xff0c;但是即使是打包成**-exec.jar&#xff0c;解压jar文件&#xff0c;可以看到里面包含了static&#xff0c;resource目录&#xf…

单片机智能家居火灾环境安全检测-分享

目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 电路图采用Altium Designer进行设计&#xff1a; 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 传统的火灾报警系统大多依赖于简单的烟雾探测器或温度传感器&#xff0c;…

C++:指针和引用

指针的基础 数据在内存当中是怎么样被存储的 数据在内存中的存储方式取决于数据的类型和计算机的体系结构 基本数据类型 整数类型&#xff1a;整数在内存中以二进制补码的形式存储。对于有符号整数&#xff0c;最高位为符号位&#xff0c;0 表示正数&#xff0c;1 表示负数。…

MySQL更换瀚高语法更换

MySQL更换瀚高语法更换 一、前言二、语句 一、前言 水一篇,mysql更换瀚高之后&#xff0c;一些需要更换的语法介绍 > 二、语句 MySQL瀚高MySQL用法瀚高用法说明ifnull(x,y)coalesce(x,y)相同相同用于检查两个表达式并返回第一个非空表达式。如果第一个表达式不是 NULL&…

亚马逊云服务器(AWS):功能、优势与使用指南

亚马逊云服务器&#xff08;AWS&#xff09;概述 亚马逊云服务器&#xff08;Amazon Web Services&#xff0c;简称AWS&#xff09;是全球领先的云计算平台&#xff0c;提供一系列强大且灵活的云服务&#xff0c;帮助企业和开发者通过云基础设施实现数据存储、计算、分析和机器…

国产三维CAD 2025新动向:推进MBD模式,联通企业设计-制造数据

本文为CAD芯智库原创整理&#xff0c;未经允许请勿复制、转载&#xff01; 上一篇文章阿芯分享了影响企业数字化转型的「MBD」是什么、对企业优化产品设计流程有何价值——这也是国产三维CAD软件中望3D 2024发布会上&#xff0c;胡其登先生&#xff08;中望软件产品规划与GTM中…