AT32/STM32使用IO口模拟串口发送

以下代码基于雅特力AT32F407VGT7,只做思路分享,感兴趣的请根据自己的芯片来移植,不管你是什么32芯片,下面代码分三部分,io模拟串口发送字节函数,io引脚初始化函数,和main函数的调用测试。

下面的注释非常清楚的解释了波特率和IO电平的关系,有什么问题欢迎在评论区讨论。

#include "at32f403a_407_board.h"

/*io模拟串口 移植时根据自己的平台实现*/
#define GPIOx GPIOA
#define GPIO_PINS_x GPIO_PINS_7
#define Delay_us(us) delay_us(us)
#define Delay_ms(ms) delay_ms(ms)
#define Tx_Pin_High gpio_bits_write(GPIOx,GPIO_PINS_x,1)
#define Tx_Pin_Low gpio_bits_write(GPIOx,GPIO_PINS_x,0)
/*说明 如果为115200 延时时间为8us   (==8.6)如果为115200 延时时间为9us   (==8.6)
    延时计算公式:baud_rate_delay = 1/BaudRate *1000000;

    BaudRate  | baud_rate_delay  | 备注

        256000  4 == 3.90625us  //实测延时4us 匹配的波特率是230400 不是256000
        128000  8 ==7.8us
        115200  9 == 8.68us
        57600   17 == 17.36us   //实测17 18 这两延时 波特率57600\56000都识别出了
        56000   18 == 17.85us   
        38400   26 == 26.04us
        19200   52 == 52.08us
        14400   69 == 69.44us
        9600    104 == 104.16
        4800    208 == 208.33
        300     3333 == 3333.33
        
    结论:其他未备注的波特率用对应baud_rate_delay延时测试发送OK
*/
//位延时时间, 改这里=改波特率
uint32_t baud_rate_delay = 3333;
/*io模拟串口 发送单个字节函数*/
static void io_to_uart_send_one_byte(char val)
{                                           
    uint8_t data_bit;
    /*start bit level is low*/
    Tx_Pin_Low;
    /*one bit delay time*/
    Delay_us(baud_rate_delay);
    
    for(data_bit = 0; data_bit < 8; data_bit++)
    { 
        if(val & 0x01)
            /*bit 1*/
            Tx_Pin_High;
        else
            /*bit 0*/
            Tx_Pin_Low;
        
        Delay_us(baud_rate_delay);
        val >>= 1;
    }
    /*stop bit level is high*/
    Tx_Pin_High;
    Delay_us(baud_rate_delay);
}
/*io模拟串口 发送多个字节函数*/ 
void io_to_uart_send(unsigned char *buf, unsigned char len)
{
    
    for(uint8_t i=0;i<len;i++)
    {
        io_to_uart_send_one_byte(buf[i]);
    }

}
/*io模拟串口 tx 引脚初始化*/ 
void io_to_uart_pin_init(void)
{
    gpio_init_type gpio_init_struct;

    /* enable the tx pin clock GPIOA*/
    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    /* set default parameter */
    gpio_default_para_init(&gpio_init_struct);
    /* configure PA.7 as with output pull-up */
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_out_type  = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_pins = GPIO_PINS_7;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;
    gpio_init(GPIOA, &gpio_init_struct);
}
int main(void)
{
    uint8_t tmp_buf[10] = {0,1,2,3,4,5,6,7,8,9};
    
    system_clock_config();
    at32_board_init();
    io_to_uart_pin_init();
    
    while(1)
    {
        io_to_uart_send(tmp_buf,10);
        delay_ms(500);

    }
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用STM32IO模拟串口发送和接收程序的示例代码: ```c #include "stm32f10x.h" #define UART_TX GPIO_Pin_0 #define UART_RX GPIO_Pin_1 #define TX_PORT GPIOA #define RX_PORT GPIOA #define BAUD_RATE 9600 void delay_us(uint32_t us) { uint32_t i = 0; for(i = 0; i < us * 8; i++); } void delay_ms(uint32_t ms) { uint32_t i = 0; for(i = 0; i < ms * 8000; i++); } void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = UART_TX; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(TX_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = UART_RX; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(RX_PORT, &GPIO_InitStructure); } void USART_SendByte(uint8_t byte) { uint8_t i = 0; GPIO_ResetBits(TX_PORT, UART_TX); delay_us(1000000 / BAUD_RATE); for(i = 0; i < 8; i++) { if(byte & 0x01) { GPIO_SetBits(TX_PORT, UART_TX); } else { GPIO_ResetBits(TX_PORT, UART_TX); } byte >>= 1; delay_us(1000000 / BAUD_RATE); } GPIO_SetBits(TX_PORT, UART_TX); delay_us(1000000 / BAUD_RATE); } uint8_t USART_ReceiveByte(void) { uint8_t byte = 0; uint8_t i = 0; while(GPIO_ReadInputDataBit(RX_PORT, UART_RX) == Bit_RESET); delay_us(1000000 / BAUD_RATE / 2); for(i = 0; i < 8; i++) { byte >>= 1; if(GPIO_ReadInputDataBit(RX_PORT, UART_RX) == Bit_SET) { byte |= 0x80; } delay_us(1000000 / BAUD_RATE); } return byte; } int main(void) { uint8_t data = 0; GPIO_Configuration(); while(1) { USART_SendByte(0xAA); delay_ms(1000); data = USART_ReceiveByte(); } } ``` 在这个例子中,我们使用PA0和PA1两个IO分别模拟串口发送和接收。首先我们需要配置GPIO的模式和速度,然后使用USART_SendByte函数向串口发送一个字节,使用USART_ReceiveByte函数从串口接收一个字节。在发送一个字节时,我们先将TX设置为低电平,然后延时一段时间,然后依次发送8个位,每个位之间都需要延时一段时间,最后将TX设置为高电平。在接收一个字节时,我们首先等待RX为高电平,然后延时一半的位时间,依次接收8个位,每个位之间都需要延时一段时间,并将接收到的位组合成一个字节返回。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值