自学内容网 自学内容网

arm-day6控制灯

1、main.c

#include"uart4.h"

#include"led.h"

//手动封装一个延时函数

void delay_ms(int ms)

{

    int i,j;

    for(i=0;i<ms;i++)

    {

        for(j=0;j<2000;j++)

        {

        }

    }

}

int main()

{

    //led的初始化

    *((unsigned int *)0x50000A28) |=(0x3<<4);

    led1_init();

    led2_init();

    led3_init();

    //uart的初始化

    uart4_config();

    char a;

    char buf[32];

    while(1)

    {

        puts(buf);

        gets(buf);//读取字符串

       

        if(!(my_strcmp("open",buf)))//打开

        {

            led1_ctl(1);

            led2_ctl(1);

            led3_ctl(1);

        }

         else if(!(my_strcmp("close",buf)))//关闭

        {

            led1_ctl(0);

            led2_ctl(0);

            led3_ctl(0);

        }

       

        else if(!(my_strcmp("11",buf)))//流水灯

        {

            for(int i=20;i>0;i--)//20的递减,可改成while(1)成死循环流水灯

            {

            led1_ctl(1);

            led2_ctl(0);

            led3_ctl(0);

            delay_ms(500);

            led1_ctl(0);

            led2_ctl(1);

            led3_ctl(0);

            delay_ms(500);

            led1_ctl(0);

            led2_ctl(0);

            led3_ctl(1);

            delay_ms(500);

            }

        }

       

       

       

     

    }

    return 0;

}

2、led.c/uart.c

#include "led.h"

void led1_init()

{

    //输出模式的配置

   GPIOE->MODER &=(~(0x3<<20));

   GPIOE->MODER |=(0x1<<20);

    //设置管脚输出类型-推挽

    GPIOE->OTYPER &=(~(0x1<<10));

    //设置输出速度

    GPIOE->OSPEEDR &=(~(0x3<<20));

    //设置上拉电阻

    GPIOE->PUPDR &=(~(0x3<<20));

   

}

void led2_init()

{

    //输出模式的配置

   GPIOE->MODER &=(~(0x3<<16));

   GPIOE->MODER |=(0x1<<16);

    //设置管脚输出类型-推挽

    GPIOE->OTYPER &=(~(0x1<<8));

    //设置输出速度

    GPIOE->OSPEEDR &=(~(0x3<<16));

    //设置上拉电阻

    GPIOE->PUPDR &=(~(0x3<<16));

   

}

void led3_init()

{

    //输出模式的配置

   GPIOF->MODER &=(~(0x3<<20));

   GPIOF->MODER |=(0x1<<20);

    //设置管脚输出类型-推挽

    GPIOF->OTYPER &=(~(0x1<<10));

    //设置输出速度

    GPIOF->OSPEEDR &=(~(0x3<<20));

    //设置上拉电阻

    GPIOF->PUPDR &=(~(0x3<<20));

   

}

//PE10的控制

void led1_ctl(int flag)

{

    if(flag==1)

    {

        GPIOE->ODR |=(0X1<<10);

    }

    else if(flag==0)

    {

        GPIOE->ODR &=(~(0X1<<10));

    }

}

//PE8的控制

void led2_ctl(int flag)

{

    if(flag==1)

    {

        GPIOE->ODR |=(0X1<<8);

    }

    else if(flag==0)

    {

        GPIOE->ODR &=(~(0X1<<8));

    }

}

//PF10的控制

void led3_ctl(int flag)

{

    if(flag==1)

    {

        GPIOF->ODR |=(0X1<<10);

    }

    else if (flag==0)

    {

        GPIOF->ODR &=(~(0X1<<10));

    }

}

#include "uart4.h"

//UART4的初始化函数

void uart4_config()

{

    //使能UART4、GPIOG\GPIOB的外设时钟

    RCC->MP_APB1ENSETR |= (0x1<<16);

    RCC->MP_AHB4ENSETR |= (0x1<<1);

    RCC->MP_AHB4ENSETR |= (0x1<<6);

    //设置PB2为复用功能

    GPIOB->MODER &=(~(0x3<<4));

    GPIOB->MODER |=(0x1<<5);

    //设置PB2为UART_RX复用功能

    GPIOB->AFRL &=(~(0xf<<8));

    GPIOB->AFRL |=(0x1<<11);

    //设置PG11为复用功能

    GPIOG->MODER &=(~(0x3<<22));

    GPIOG->MODER |=(0x1<<23);

    //设置PG11为UART_TX复用功能

    GPIOG->AFRH &=(~(0xf<<12));

    GPIOG->AFRH |=(0x6<<12);

    //禁用串口,UE=0

    USART4->CR1 &=(~0x1);

    //设置8位数据位

    USART4->CR1 &=(~(0x1<<12));

    USART4->CR1 &=(~(0x1<<28));

    //设置无奇偶校验

    USART4->CR1 &=(~(0x1<<10));

    //设置1位停止位

    USART4->CR2 &=(~(0x3<<12));

    //设置波特率为115200

    USART4->BRR = 0x22b;

    //设置频率不分频

    USART4->PRESC &=(~0xF);

    //设置16倍过采样倍数

    USART4->CR1 &=(~(0x1<<15));

    //使能发送器

    USART4->CR1 &=(~(0x1<<3));

    USART4->CR1 |=(0x1<<3);

    //使能接收器

    USART4->CR1 &=(~(0x1<<2));

    USART4->CR1 |=(0x1<<2);                            

    //使能串口

    USART4->CR1 |= (0x1);

}

//封装单个字符发送函数

void putchar(char c)

{

    //判断发送数据寄存器是否为空,不为空则阻塞等待

    while(!(USART4->ISR&(0X1<<7)));

    //当为空时将数据写入到数据发送寄存器

    USART4->TDR=c;

    //阻塞等待数据发送完毕,函数结束

    while(!(USART4->ISR&(0X1<<6)));

}

//封装单个字符接收的函数

char getchar()

{

    //判断接收数据寄存器中有没有有效数据。如果没有就阻塞等待,如果有直接读取

    while(!(USART4->ISR&(0X1<<5)));

    //将读取的数据返回

    return USART4->RDR;

}

//发送一个字符串

void puts(char *s)

{

    while(*s)

    {

        putchar(*s);

        s++;

    }

    //发送完字符串让光标显示在下一行最开头

    putchar('\n');

    putchar('\r');

}

//接收字符串

void gets(char *s)

{

    while(1)

    {

        *s=getchar();

        putchar(*s);//将读取到的字符回显到串口

        if(*s=='\r')

        {

            break;

        }

        s++;

    }

    *s='\0';//手动补上一个'\0'

    putchar('\n');//让光标显示在下一行

}

//比较函数

int my_strcmp(char* str1, char* str2)//strcmp函数具体实现。

{

    while ((*str1 != '\0') && (*str1 == *str2))//判断字符串是否结束。

    {

        str1++;

        str2++;//

    }

    int t;

    t = *str1 - *str2;//比较对应字符大小。

    return t;//若相等返回0,前者大返回正值,后者大则负。

}

3、led.h/uart.h

#ifndef __LED_H__

#define __LED_H__

#include"stm32mp1xx_gpio.h"

#include"stm32mp1xx_rcc.h"

void led1_init();

void led2_init();

void led3_init();

void led1_ctl(int flag);

void led2_ctl(int flag);

void led3_ctl(int flag);

#endif

#ifndef __UART4_H__

#define __UART4_H__

#include"stm32mp1xx_gpio.h"

#include"stm32mp1xx_rcc.h"

#include"stm32mp1xx_uart.h"

void uart4_config();

void putchar(char c);

char getchar();

void puts(char *s);

void gets(char *s);

int my_strcmp(char* str1, char* str2);

#endif


原文地址:https://blog.csdn.net/weixin_51648475/article/details/139102056

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!