串口实现字符与字符串的收发

需求:

1初始化RCC、GPIO、UART相关寄存器,并实现单个字符

2初始化RCC、GPIO、UART相关寄存器,并实现字符串的收发

3 用swi指令验证软中断流程

需求1 2 :代码实现过程:

头文件

#ifndef __UART4_H__
#define __UART4_H__

#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_uart.h"

//串口初始化
void uart_init();

//发送一个字符
void uart_put_char(const char str);

//发送一个字符串
void uart_put_string(const char* str);

//接收一个字符
char uart_get_char();

//接收一个字符串
char* uart_get_string();

#endif

源文件

#include "uart4.h"

extern void delay_ms(int ms);

//串口初始化
void uart_init()
{
     /*********RCC章节初始化************/
    RCC->MP_AHB4ENSETR |= (0x1 << 1);
    RCC->MP_AHB4ENSETR |= (0x1 << 6);
    RCC->MP_APB1ENSETR |= (0x1 << 16);
     /*********GPIO章节初始化************/
    GPIOB->MODER &= (~(0x3 << 4));
    GPIOG->MODER &= (~(0x3 << 22));
    GPIOB->MODER |= (0x1 << 5);
    GPIOG->MODER |= (0x1 << 23);

    /*
    GPIOB->OTYPER &= (~(0x1 << 2));
    GPIOG->OTYPER &= (~(0x1 << 11));
    
    GPIOB->OSPEEDR &= (~(0x3 << 4));
    GPIOG->OSPEEDR &= (~(0x3 << 22));

    GPIOB->PUPDR &= (~(0x3 << 4));
    GPIOG->PUPDR &= (~(0x3 << 22));
    */

    GPIOB->AFRL &= (~(0xF << 8));
    GPIOB->AFRL |= (0x8 << 8);
    GPIOE->AFRH &= (~(0xF << 12));
    GPIOE->AFRH |= (0x6 << 12);

    //ODR?

    

     /*********UART4章节初始化************/
    //0.判断UE位的值
    if(USART4->CR1 & (0x1))
    {
        delay_ms(50);
    }
    //1.设置8N1中的8:8位数据位
    USART4->CR1 &= (~(0x1 << 28));
    USART4->CR1 &= (~(0x1 << 12));
    //2.设置8N1中的N:无校验位
    USART4->CR1 &= (~(0x1 << 10));
    //3.设置8N1中的1:一位停止位
    USART4->CR2 &= (~(0x3 << 12));
    //4.设置采样频率为16倍
    USART4->CR1 &= (~(0x1 << 15));
    //5.先分频    
    USART4->PRESC &= (~(0xF));
    //6.然后再设置波特率
    USART4->BRR |= 0x22b;
    //7.使能TE与RE
    USART4->CR1 |= (0x3 << 2);
    //8.最后使能UE
    USART4->CR1 |= (0x1);
    
}

//发送一个字符
void uart_put_char(const char str)
{
    //1.判断发送数据寄存器是否为空,为空,才可以发送下一个字节
    //ISR[7]  
    //读0:发送数据寄存器满,需要等待
    //读1:发送数据寄存器空,才可以发送下一个位数据
    while(!(USART4->ISR & (0x1 << 7)));

    //2.将要发送的字符,写到发送数据寄存器中
    USART4->TDR = str;

    //3.判断发送数据是否完成 ISR[6]
    while(!(USART4->ISR & (0x1 << 6)));
}

//发送一个字符串
void uart_put_string(const char* str)
{
    const char* p = str;
    while(*p != '\0'){
        uart_put_char(*p);
        p++;
    }
    //判断是否为'\0',一个字符一个字符发送
}

//接收一个字符
char uart_get_char()
{
    char ch;
    //1.判断接收数据寄存器是否有数据可读 ISR[5]
    while(!(USART4->ISR & (0x1 << 5)));
    
    
    //2.将接收到的数据读出来
    ch = USART4->RDR;
    return ch;
}

char buffer[50] = {0};
//接收一个字符串
char* uart_get_string()
{
    int i=0;
    //for循环
    for(i = 0;i<48;i++){
        buffer[i]=uart_get_char();
        if(buffer[i]=='\r') break;
        uart_put_char(buffer[i]);
    }
    //当键盘的回车键'\r'按下之后,字符串输入完成
    
    //字符串补 '\n' '\0'
    uart_put_char('\r');
    uart_put_char('\n');
    buffer[i+1] = '\n';
    buffer[i+2] = '\0';
    return buffer;
}

测试文件

#include "uart4.h"

extern void printf(const char *fmt, ...);

void delay_ms(int ms)
{
    int i,j;
    for(i = 0; i < ms;i++)
        for (j = 0; j < 1800; j++);
}

int main()
{
    //串口初始化
    uart_init();
    //实现串口数据收发
    uart_put_string("××××testing××××\r\n");
    while(1)
    {
    //    uart_put_char(uart_get_char()+1);
        uart_put_string(uart_get_string());
    }
    return 0;
}

需求3:

@ '@'
.text
.globl _start

_start:

    @1.构建异常向量表
    b reset
    b undefine
    b software_interrupt
    b prefetch_abort
    b data_abort
    b .
    b irq
    b firq
    
stop:    @stop标签入口,相当于while(1)循环,防止程序跑飞
    b stop
    
reset:
    @2.异常源---->标签
    @3.系统一上电处于SVC模式
    ldr sp,=0x40000800
    @4.从SVC模式切换到user模式
    msr cpsr,#0xD0
    @5.user模式实现如下内容
        @1>初始化栈指针
        ldr sp,=0x40000700
        @2>分别对r0,r1寄存器赋值
        mov r0,#0x1
        mov r1,#0x2
        @3>执行软中断指令----->四大步三小步
        swi 2
    add r0,r0,r1 @ r0 = 0x1 + 0x2 = 0x3
    b stop
    
undefine:
software_interrupt:
    @6.SVC模式下执行内容
        @1>压栈保存现场
        stmfd sp!,{r0-r12,lr}
        @2>分别对r0,r1寄存器赋值
        mov r0,#0x2
        mov r1,#0x3
        add r0,r0,r1        
        @3>恢复现场
        ldmfd sp!,{r0-r12,pc}
        @^:代表将SPSR_<mode>寄存器中的值,恢复给CPSR    
prefetch_abort:
data_abort:
irq:
firq:

.end    @结束标志
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值