• 51单片机IO口模拟UART串口通信


    #include <reg52.h>
    #include "main.h"
    #include "smartcard.h"
    #include "stdio.h"

    typedef enum { false, true }bool;

    #if 0
    sbit PIN_RXD = P1^0; //接收发送同一个引脚定义
    sbit PIN_TXD = P1^0; //接收发送同一个发送引脚定义
    sbit PIN_CLK = P3^1; //智能卡时钟引脚定义
    sbit PIN_3v5v = P3^2; //智能卡3v_5v引脚定义
    sbit PIN_RST = P3^3; //智能卡复位引脚定义
    sbit PIN_CMDVCC = P3^4; //智能卡CMD引脚定义
    #else
    // test Parity
    sbit PIN_RXD = P1^0; //接收 脚定义
    sbit PIN_TXD = P1^2; //发送 脚定义
    sbit PIN_CLK = P3^5; //智能卡时钟引脚定义
    sbit PIN_3v5v = P3^2; //智能卡3v_5v引脚定义
    sbit PIN_RST = P3^3; //智能卡复位引脚定义
    sbit PIN_CMDVCC = P3^4; //智能卡CMD引脚定义

    sbit Test_CLK = P0^3; //接收 脚定义

    #endif

    bit RxdOrTxd = 0; //指示当前状态为接收还是发送
    bit RxdEnd = 0; //接收结束标志
    bit TxdEnd = 0; //发送结束标志
    uint8_t RxdBuf = 0; //接收缓冲器
    uint8_t TxdBuf = 0; //发送缓冲器
    void ConfigUART(unsigned int baud);
    void StartTXD(unsigned char dat);
    void StartRXD();
    void test_IO();

    //通过嵌套宏定义,制作一张包括0~255各个数字中包含1的个数,其中包含偶数个1,则ParityTable256[i]=0,否则ParityTable256[i]=1;


    static const bool ParityTable256[256] =
    {
    #define P2(n) n, n^1, n^1, n
    #define P4(n) P2(n), P2(n^1), P2(n^1), P2(n)
    #define P6(n) P4(n), P4(n^1), P4(n^1), P4(n)
    P6(0), P6(1), P6(1), P6(0)
    };


    void mainb(){
    EA = 1; //开总中断
    ConfigUART(9600);//配置波特率为 9600
    while (1){
    while (PIN_RXD); //等待接收引脚出现低电平,即起始位
    StartRXD(); //启动接收
    while (!RxdEnd); //等待接收完成
    StartTXD(RxdBuf+1); //接收到的数据+1 后,发送回去
    while (!TxdEnd); //等待发送完成
    }
    return;
    }

    void SET_3v5v()
    {
    PIN_3v5v=1;
    }
    void RESET_3v5v()
    {
    PIN_3v5v=0;
    }

    void RST_SET(BitAction ResetState)
    {

    PIN_RST = ResetState;
    }

    void SET_CMVCC()
    {
    PIN_CMDVCC =1;
    }
    void RESET_CMVCC()
    {
    PIN_CMDVCC =0;
    }

    /* 串口配置函数,baud-通信波特率 */
    void ConfigUART(unsigned int baud){
    TMOD &= 0xF0; //清零 T0 的控制位
    TMOD |= 0x02; //配置 T0 为模式 2
    // TH0 = 256 - (11059200/6)/baud; //计算 T0 重载值
    TH0 = 256 - (FOSC/12)/baud; //计算 T0 重载值

    }
    /* 启动串行接收 */
    void StartRXD(){


    while (PIN_RXD);
    //printf("PIN_RXD2=0x%02X ", (int)PIN_RXD);
    TL0 = 256 - ((256-TH0)>>1); //接收启动时的 T0 定时为半个波特率周期
    ET0 = 1; //使能 T0 中断
    TR0 = 1; //启动 T0
    RxdEnd = 0; //清零接收结束标志
    RxdOrTxd = 0; //设置当前状态为接收

    }
    /* 启动串行发送,dat-待发送字节数据 */
    void StartTXD(uint8_t dat){
    TxdBuf = dat; //待发送数据保存到发送缓冲器
    TL0 = TH0; //T0 计数初值为重载值
    ET0 = 1; //使能 T0 中断
    TR0 = 1; //启动 T0
    PIN_TXD = 0; //发送起始位
    TxdEnd = 0; //清零发送结束标志
    RxdOrTxd = 1; //设置当前状态为发送
    }

    uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
    {
    /* Check the parameters */
    // assert_param(IS_USART_ALL_PERIPH(USARTx));

    /* Receive Data */
    #if 0
    uint16_t tt= USARTx->SR ;
    USARTx->SR = tt & (uint16_t)0x3df; //wuhh add ,remove later

    return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
    #endif
    return (uint16_t) RxdBuf;

    }
    void USART_SendData(USART_TypeDef* USARTx, uint8_t Data)
    {
    StartTXD(Data);
    }
    FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
    {
    FlagStatus bitstatus = RESET;
    if (USART_FLAG== USART_FLAG_TC)
    if (TxdEnd)
    {
    bitstatus = SET;
    }
    else
    {
    bitstatus = RESET;
    }

    if (USART_FLAG== USART_FLAG_RXNE)
    if (RxdEnd)
    {
    bitstatus = SET;
    }
    else
    {
    bitstatus = RESET;
    }
    return bitstatus;
    }
    static bit polarity = 0; //输出智能卡时钟极性

    #if 1

    /* T0 中断服务函数,处理串行发送和接收 */
    void InterruptTimer0() interrupt 1{

    static unsigned char cnt = 0; //位接收或发送计数
    Test_CLK = !Test_CLK;

    if (RxdOrTxd)
    { //串行发送处理
    cnt++;
    if (cnt <= 8){ //低位在先依次发送 8bit 数据位
    PIN_TXD = TxdBuf & 0x01;
    TxdBuf >>= 1;
    }else
    if (cnt == 9)
    { //发送停止位
    PIN_TXD = 1;
    }
    else{ //发送结束
    cnt = 0; //复位 bit 计数器
    TR0 = 0; //关闭 T0
    TxdEnd = 1; //置发送结束标志
    }
    }
    else{ //串行接收处理
    if (cnt == 0){ //处理起始位
    if (!PIN_RXD){ //起始位为 0 时,清零接收缓冲器,准备接收数据位
    RxdBuf = 0;
    cnt++;
    }
    else{ //起始位不为 0 时,中止接收
    TR0 = 0; //关闭 T0
    }
    }else if (cnt <= 8){ //处理 8 位数据位
    RxdBuf >>= 1; //低位在先,所以将之前接收的位向右移
    //接收脚为 1 时,缓冲器最高位置 1,
    //而为 0 时不处理即仍保持移位后的 0
    if (PIN_RXD){
    RxdBuf |= 0x80;
    }
    cnt++;
    }else{ //停止位处理
    cnt = 0; //复位 bit 计数器
    TR0 = 0; //关闭 T0
    if (PIN_RXD){ //停止位为 1 时,方能认为数据有效
    RxdEnd = 1; //置接收结束标志
    }
    }
    }
    }

    #else
    /* T0 中断服务函数,处理串行发送和接收 */

    void InterruptTimer0() interrupt 1{

    static unsigned char cnt = 0; //位接收或发送计数
    //test_IO();
    #if 0
    PIN_TXD = !PIN_TXD;
    #else

    if (RxdOrTxd){ //串行发送处理
    cnt++;
    if (cnt <= 8){ //低位在先依次发送 8bit 数据位
    PIN_TXD = TxdBuf & 0x01;
    TxdBuf >>= 1;
    }else if (cnt == 9){ //奇偶位
    PIN_TXD=ParityTable256[TxdBuf];
    }else if (cnt == 10){ //发送停止位1 智能卡协议共两个停止位
    PIN_TXD = 1;
    }else if (cnt == 11){ //发送停止位2
    PIN_TXD = 1;
    }else{ //发送结束
    cnt = 0; //复位 bit 计数器
    TR0 = 0; //关闭 T0
    TxdEnd = 1; //置发送结束标志
    }
    }else{ //串行接收处理
    if (cnt == 0){ //处理起始位
    if (!PIN_RXD){ //起始位为 0 时,清零接收缓冲器,准备接收数据位
    RxdBuf = 0;
    cnt++;
    //printf("InterruptTimer 0 ");
    } else{ //起始位不为 0 时,中止接收
    TR0 = 0; //关闭 T0
    printf("InterruptTimer close ");
    }
    }
    else if (cnt <= 8){ //处理 8 位数据位
    RxdBuf >>= 1; //低位在先,所以将之前接收的位向右移
    //接收脚为 1 时,缓冲器最高位置 1,
    //而为 0 时不处理即仍保持移位后的 0
    if (PIN_RXD){
    RxdBuf |= 0x80;
    }
    printf("RxdBuf=0x%02X ", (int)RxdBuf);
    cnt++;
    }else{ //停止位处理
    cnt = 0; //复位 bit 计数器
    TR0 = 0; //关闭 T0
    if (PIN_RXD){ //停止位为 1 时,方能认为数据有效
    RxdEnd = 1; //置接收结束标志
    }
    }
    }
    #endif
    }
    #endif

  • 相关阅读:
    Dynamics CRM 365 查询安全角色的具体权限明细
    Dynamics CRM 365 JS易错备忘录
    Dynamics CRM 365 9.0版本,在活动增加phonecall和task的时候,在postCreate同步触发的时候拿不到regardingobjectid
    Dynamics 365 通过插件中的retrievemultiple消息来过滤产品视图
    【短视频】达人是什么?
    跨境电商业务知识
    【电商行业】商品标签有哪些?
    二维高斯核函数
    php模拟发送post请求
    scp
  • 原文地址:https://www.cnblogs.com/wuhh123/p/11367595.html
Copyright © 2020-2023  润新知