利用定时器1产生全双工软件串口

代码;

/*
  《AVR专题精选》随书例程
  
  3.通信接口使用技巧

  项目:使用AVR定时器1和外中断实现全双工软件串口
  文件:softuart.c
  说明:软件串口驱动文件
        
  作者:邵子扬
  时间:2012年12月16日

*/
#include "softuart.h"

// 内部变量
struct TSOFTUART stUART;

// 软件串口初始化
void sfUART_init(void)
{
  // 设置IO状态
  PINDIR(sfUART_TXDIO, PIN_OUTPUT);
  PINSET(sfUART_TXDIO);
  PINDIR(sfUART_RXDIO, PIN_INPUT);
  PINSET(sfUART_RXDIO);
  
  // 内部变量初始化
  stUART.TXDcnt = 0;
  stUART.RXDcnt = 0;
  stUART.sfTXC = 0;
  stUART.sfRXC = 0;

  // 定时器初始化
  // CTC Mode
  // 分频比: 1
  OCR1A = 1;
  ICR1  = (F_CPU / sfBAUDRATE) - 1;
  TCCR1A = 0x00;
  TCCR1B = (1 << WGM13)|(1 << WGM12)|(1 << CS10);
  TIMSK = (1 << OCIE1A)|(0 << OCIE1B);

  // 外中断初始化
  // INT1
  // 允许外中断1,下降沿触发方式
  MCUCR = (1 << ISC11);
  sf_ENABLE_RXINT();

}

// 检查数据接收标志
char sfUART_RXC(void)
{
  return stUART.sfRXC;
}

// 检查数据发送完成标志
char sfUART_TXC(void)
{
  return stUART.sfTXC;
}

// 清除数据发送完成标志位
void sfUART_clrTXC(void)
{
  stUART.sfTXC = 0;
}

// 读取数据
char sfUART_getbyte(void)
{
  stUART.sfRXC = 0;
  return stUART.RXDBUF;
}

// 发送数据
void sfUART_sendbyte(char dat)
{
  stUART.TXDBUF = dat;
  stUART.sfTXC = 0;
  stUART.TXDcnt = 1;
}

// 软件串口数据发送服务程序
void sfUART_TXDsvr(void)
{
  switch(stUART.TXDcnt)
  {
    case 0:// 无数据
      return;
    case 1:// 发送起始位
      stUART.TXDcnt++;
      PINCLR(sfUART_TXDIO);
      break;
    case 2:// 发送数据
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
      if(stUART.TXDBUF & 0x01)
        PINSET(sfUART_TXDIO);
      else
        PINCLR(sfUART_TXDIO);
      stUART.TXDBUF = stUART.TXDBUF >> 1;
      stUART.TXDcnt++;
      break;
    case 10:// 发送停止位
      stUART.TXDcnt = 0;
      PINSET(sfUART_TXDIO);
      stUART.sfTXC = 1;
      break;
    default:
      stUART.TXDcnt = 0;
      return;

  }
}

// 软件串口数据接收服务程序
void sfUART_RXDsvr(void)
{
  switch(stUART.RXDcnt)
  {
    case 0:// 接收起始位
      stUART.RXDBUF = 0;
      stUART.RXDcnt++;
      break;
    case 1:// 接收数据位
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      stUART.RXDBUF = stUART.RXDBUF >> 1;
      if(PININ(sfUART_RXDIO))
        stUART.RXDBUF |= 0x80;
      stUART.RXDcnt++;
      break;
    case 9:// 停止位
      stUART.sfRXC = 1;
      sf_RXD_STOP();
      GIFR |= (1<<INTF1);
      sf_ENABLE_RXINT();
      break;
    default:
      return;
  }
}

main.c

/*
  《AVR专题精选》随书例程
  
  3.通信接口使用技巧

  项目:使用AVR定时器1和外中断实现全双工软件串口
  文件:main.c
  说明:主程序,演示软件串口的使用方法
        
  作者:邵子扬
  时间:2012年12月16日

*/
#include "cfg.h"
#include "macromcu.h"
#include "softuart.h"

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define UBRRREG  (F_CPU / ( 8 * sfBAUDRATE ) - 1)

// 定时器1 COMPA中断服务程序
ISR(TIMER1_COMPA_vect, ISR_NOBLOCK)
{
  sfUART_TXDsvr();  // 软件串口发送服务程序
}

// 定时器1 COMPB中断服务程序
ISR(TIMER1_COMPB_vect, ISR_NOBLOCK)
{
  sfUART_RXDsvr();  // 软件串口接收服务程序
}

// 外中断服务程序
ISR(INT1_vect)
{
  sf_DISABLE_RXINT();  // 禁止外中断, 避免重复触发
  sf_RXD_START();      // 启动接收程序
}

int main(void)
{
  unsigned char tmp;

  PORTB = 0xFF;        // 仿真时, PB2(SS)需要设置为高电平
                       // 否则会出错. 实际使用时不需要

  sfUART_init();       // 初始化软件串口

  // 使用硬件串口作为对比
  UBRRH = UBRRREG / 256;
  UBRRL = UBRRREG % 256;
  UCSRA = ( 1 << U2X );
  UCSRB = ( 1 << TXEN );
  UCSRC = ( 1 << UCSZ1) | ( 1 << UCSZ0 );
  
  sei(); // 开中断


  for(;;)
  {

    if(sfUART_RXC())  // 接收到新数据
    {
      tmp = sfUART_getbyte(); // 读取数据
      UDR = tmp;              // 发送到硬件串口
      sfUART_sendbyte(tmp);   // 发送到软件串口
    }
    if(sfUART_TXC())  // 数据发送完成
    {
      sfUART_clrTXC();// 清除发送完成标志
    }

  }

  return 0;

}

仿真效果图:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

达梦数据守护集群部署

接上篇 达梦8单机规范化部署 https://blog.csdn.net/qq_25045631/article/details/139898690 1. 集群规划 在正式生产环境中&#xff0c;两台机器建议使用统一配置的服务器。使用千兆或千兆以上网络。 两台虚拟机各加一块网卡&#xff0c;仅主机模式&#xff0c;作为心跳网卡…

【日记】原来真的有人不适合谈恋爱(1194 字)

正文 21 日正是周五&#xff0c;夏至。全年当中&#xff0c;白天时长最长的一天。而恰好那天也是银行扣息的日子。所以很忙&#xff0c;我差点没能走掉。 所幸最终还是有惊无险。 到斯的家里&#xff0c;是晚上 9 点钟。比我想得要早。这个周周四&#xff0c;他过生日。但是那天…

提升效率新选择——运营必备API合集

在数字化、自动化的时代背景下&#xff0c;运营小工具API已经成为了众多企业不可或缺的重要组成部分。这些API工具为运营工作提供了极大的便利&#xff0c;不仅简化了工作流程&#xff0c;还提高了工作效率。 运营小工具API是针对运营工作特定需求而设计的接口&#xff0c;通过…

7.系统工具——黑马程序员Java最新AI+若依框架项目

目录 前言一、表单构建任务&#xff1a;设计添加课程表单 二、 代码生成1.任务&#xff1a;将部门表在页面端显示改为树形结构 三、系统接口任务&#xff1a;使用sagger进行接口测试 前言 提示&#xff1a;本篇讲解若依框架 系统工具 一、表单构建 功能&#xff1a;完成前端…

【持续集成_01课_Git版本管理及基本应用】

一、什么是持续集成 测试代码、开发代码、测试报告、发送邮件...组合到一起来 --- 流水线。 &#xff08;有一个规范的流程&#xff09; 持续集成&#xff08;Continuous Integration&#xff0c;简称CI&#xff09; 是一种软件开发实践&#xff0c;旨在将代码集成到共享仓库…

网页抓取和网页爬取之间有何区别?

随着互联网的发展和信息的爆炸式增长&#xff0c;数据收集和处理已成为企业和个人不可或缺的需求。在此背景下&#xff0c;网页抓取和网络爬虫已成为两种常见的数据收集方法。虽然这两种方法看似相似&#xff0c;但它们的方法和目标存在显著差异。本文将为您详细介绍网页抓取和…

【科技前沿】电子设计新贵SmartEDA:为何它引领行业风潮?

在当今这个电子科技日新月异的时代&#xff0c;电子设计工具如同设计师的魔法棒&#xff0c;不断推动着产品创新的速度。而近期&#xff0c;一款名为SmartEDA的电子国产设计仿真软件异军突起&#xff0c;成为了行业内的新宠。那么&#xff0c;SmartEDA究竟有何过人之处&#xf…

人工和AI大语言模型成本对比 ai语音模型

这里既有AI&#xff0c;又有生活大道理&#xff0c;无数渺小的思考填满了一生。 上一专题搭建了一套GMM-HMM系统&#xff0c;来识别连续0123456789的英文语音。 但若不是仅针对数字&#xff0c;而是所有普通词汇&#xff0c;可能达到十几万个词&#xff0c;解码过程将非常复杂…

# bash: chkconfig: command not found 解决方法

bash: chkconfig: command not found 解决方法 一、chkconfig 错误描述&#xff1a; 这个错误表明在 Bash 环境下&#xff0c;尝试执行 chkconfig 命令&#xff0c;但是系统找不到这个命令。chkconfig 命令是一个用于管理 Linux 系统中服务的启动和停止的工具&#xff0c;通常…

ChatGPT对那些带有残疾迹象的简历有偏见——但它可以改善

ChatGPT对那些带有残疾迹象的简历有偏见——但它可以改善 去年&#xff0c;华盛顿大学(University of Washington)研究生凯特•格拉兹科(Kate Glazko)在寻找研究实习机会时注意到&#xff0c;招聘人员在网上发布消息称&#xff0c;他们使用OpenAI的ChatGPT和其他人工智能工具来…

【b站-湖科大教书匠】3 数据链路层-计算机网络微课堂

课程地址&#xff1a;【计算机网络微课堂&#xff08;有字幕无背景音乐版&#xff09;】 https://www.bilibili.com/video/BV1c4411d7jb/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 3 数据链路层 3.1 数据链路层概述 3.1.1 数据链路层在网络体系结…

Eureka 服务注册与发现

目录 前言 注册中心 CAP 理论 常⻅的注册中心 CAP理论对比 Eureka 搭建 Eureka Server 引⼊ eureka-server 依赖 完善启动类 编写配置⽂件 启动服务 服务注册 引⼊ eureka-client 依赖 完善配置⽂件 启动服务 服务发现 引⼊依赖 完善配置⽂件 远程调⽤ 启动…

【设计模式深度剖析】【9】【行为型】【访问者模式】| 以博物馆的导览员为例加深理解

&#x1f448;️上一篇:备忘录模式 | 下一篇:状态模式&#x1f449;️ 设计模式-专栏&#x1f448;️ 文章目录 访问者模式定义英文原话直译如何理解呢&#xff1f; 访问者模式的角色类图代码示例 访问者模式的应用优点缺点使用场景 示例解析:博物馆的导览员代码示例 访问…

uni-app与原生插件混合开发调试3-安卓原生插件开发调试和打包

安卓原生插件开发调试和打包 上面已经介绍了怎么安装开发和调试环境&#xff0c;接下来就是安卓原生插件的具体开发和调试步骤&#xff1a; 将uniapp前端项目的index.vue文件新增代码。代码如图所示&#xff1a; <template><view><view><text>{{titl…

GaussDB关键技术原理:高性能(二)

GaussDB关键技术原理&#xff1a;高性能&#xff08;一&#xff09;从数据库性能优化系统概述对GaussDB的高性能技术进行了解读&#xff0c;本篇将从查询处理综述方面继续分享GaussDB的高性能技术的精彩内容。 2 查询处理综述 内容概要&#xff1a;本章节介绍查询端到端处理的…

Go团队的工作方式

在Go 1.23版本[1]即将发布(2024.8)之前&#xff0c;在GopherCon 2024[2]开幕(2024.7)之前&#xff0c;Go团队成员Cameron Balahan(Go产品负责人)[3]、 Sameer Ajmani&#xff08;Go团队工程总监&#xff09;和Russ Cox&#xff08;Go团队技术负责人&#xff09;[4]参加了业界知…

2024 年最新 Python 基于火山引擎豆包大模型搭建 QQ 机器人详细教程(更新中)

豆包大模型概述 火山引擎官网&#xff1a;https://www.volcengine.com/ 字节跳动推出的自研大模型。通过字节跳动内部50业务场景实践验证&#xff0c;每日千亿级tokens大使用量持续打磨&#xff0c;提供多模态能力&#xff0c;以优质模型效果为企业打造丰富的业务体验。 模型…

“论云原生架构及其应用”写作框架,系统架构设计师

论文真题 近年来&#xff0c;随着数字化转型不断深入&#xff0c;科技创新与业务发展不断融合&#xff0c;各行各业正在从大工业时代的固化范式进化成面向创新型组织与灵活型业务的崭新模式。在这一背景下&#xff0c;以容器和微服务架构为代表的云原生技术作为云计算服务的新…

智能化改造助力企业高质量发展

引言 背景介绍 在当今全球经济环境中&#xff0c;变化和不确定性已成为常态。企业面临的竞争压力不断增加&#xff0c;市场竞争日益激烈。新兴市场的崛起、技术进步和消费者需求的快速变化&#xff0c;使得传统的商业模式和生产方式面临巨大挑战。为了在这样的环境中保持竞争力…