说明:如果大家图库中没有对应照片,可以直接在我的gitee或这github上对我完整的代码进行下载与使用(我的图库文件pic.h)

紧急说明:本文使用的LCD_Show_Chinese这个是我封装的函数,这个函数我会在下一将进行展示

1.串口3的移植与使用

  1. 先找到串口3所挂载的总线上->然后找另外一个数据手册查询串口3所使用的引脚

    CH32FV2x_V3xRM

    CH32V307DS0(查引脚)

  2. 重新创建一个工程(按照上一章的操作)

  3. 将串口中断和串口初始化还有快速中断cv下来进行项目的开发与使用(大家只需要会修改引脚即可看得懂,大概看得懂代码的意思,知道代码该怎么用就行)-可以使用ai进行辅助开发

    串口初始化(进行串口移植时只需要把串口3的名称,挂载总线,引脚初始化进行修改即可)-注意:一定要查看对应的挂载总线APB

    void Usart3_Init()
    {
        GPIO_InitTypeDef  GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef  NVIC_InitStructure;
    
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 , ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
    
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    
        GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    
        USART_InitStructure.USART_BaudRate = 115200;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
    
    
    
        USART_Init(USART3, &USART_InitStructure);
        USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
    
    
    
         NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
         NVIC_Init(&NVIC_InitStructure);
    
         USART_Cmd(USART3, ENABLE);
         
    }

    串口中断

    void USART3_IRQHandler(void)
    {
        u8 temp;
        if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
        {
            temp=USART_ReceiveData(USART3);
    		USART_SendData(USART3, temp+1);
        }
        USART_ClearITPendingBit(USART3, USART_IT_RXNE);
    }

    串口快速中断(放置在#include<xxx.h>下方)

    void TIM3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));//定时器3快速中断
  4. 主函数的书写->编译下载

    int main(void)
    {
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
    	SystemCoreClockUpdate();//时钟配置
    	//USART_Printf_Init(115200);//串口1初始化
    	Delay_Init();//延时函数初始化
    	Usart3_Init();
        GPIO_InitTypeDef GPIO_InitStructure = {0};//定义了一个GPIO的结构体
    
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//打开了GPIO外设的时钟
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//GPIO的三种模式
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);//将结构体的首地址传入
    
    
    	while(1)
        {
    	    USART_SendData(USART3, 'a');
    	    Delay_Ms(1000);
    	}
    }
  5. 接线-使用USB-TTL连接板子上的串口3-注意与单片机共地->使用串口助手观察现象(首先查看是否接收到a,然后通过串口助手发送1查看是否回复2)

2.SG90舵机的移植与使用-PWM控制

  1. 重新建立工程来书写

  2. 首先将第一讲的LED使用到的PC2引脚初始化cv过来

    int main(void)
    {
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
    	SystemCoreClockUpdate();//时钟配置
    	//USART_Printf_Init(115200);//串口1初始化
    	Delay_Init();//延时函数初始化
    	
        GPIO_InitTypeDef GPIO_InitStructure = {0};//定义了一个GPIO的结构体,用来传参
    
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//打开了GPIO外设的时钟
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//GPIO的三种设置(引脚)-由于我选择连接LED1的引脚为PC2
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO的三种设置(模式)-推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO的三种设置(速度)
        GPIO_Init(GPIOC, &GPIO_InitStructure);//将结构体的首地址传入
    
    
    	while(1)
        {
    
    	}
    }
  3. 接线说明-PC2与SG90的PWM的那条线相连

  4. 书写舵机控制代码-验证舵机接线是否有误

    	while(1)
        {
        GPIO_ResetBits(GPIOC, GPIO_Pin_2);
    	Delay_Ms(20);
    	GPIO_SetBits(GPIOC, GPIO_Pin_2);
    	Delay_Us(1500);
    	}
  5. 删去刚刚的引脚初始化

  6. 定时器控制SG90舵机-可以生成更精确的PWM波(注意这里我使用的PWM引脚是PA0)

    定时器初始化以及引脚初始化书写

    // 定义舵机的PWM周期和占空比
    #define PWM_PERIOD 20000  // PWM周期为20ms (20000us)
    #define PWM_MIN 500       // 最小脉宽为0.5ms (500us)
    #define PWM_MAX 2500      // 最大脉宽为2.5ms (2500us)
    
    //定时器初始化
    
    // 初始化TIM2以生成PWM信号-
    void TIM2_PWM_Init(void)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  // 使能TIM2时钟
    
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        TIM_OCInitTypeDef TIM_OCInitStructure;
    
        // 配置TIM2的基本参数
        TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD - 1;  // 设置自动重装值
        TIM_TimeBaseStructure.TIM_Prescaler = 96 - 1;       // 设置预分频器,96MHz/96 = 1MHz (1us)
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    
        // 配置TIM2的PWM模式
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = PWM_MIN;  // 初始占空比为最小值
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    
        // 配置TIM2通道1
        TIM_OC1Init(TIM2, &TIM_OCInitStructure);  // 使用TIM2的通道1
        TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);  // 使能TIM2通道1的预装载寄存器
    
    
        TIM_ARRPreloadConfig(TIM2, ENABLE);               // 使能TIM2的自动重装寄存器预装载
    
        TIM_Cmd(TIM2, ENABLE);  // 使能TIM2
    }
    
    //PWM引脚初始化
    void GPIO_Pwm_Init(void)
    {
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  // 使能GPIOA时钟
        GPIO_InitTypeDef GPIO_InitStructure = {0};//定义了一个GPIO的结构体,用来传参
    	
    
            // 配置PA0为复用推挽输出(TIM2通道1)
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    
    }
  7. 主函数的书写

    int main(void)
    {
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
    	SystemCoreClockUpdate();//时钟配置
    	//USART_Printf_Init(115200);//串口1初始化
    	Delay_Init();//延时函数初始化
    	TIM2_PWM_Init();//定时器初始化
    	GPIO_Pwm_Init();//GPIO初始化
    	TIM_SetCompare1(TIM2, 1500);//设置占空比
    	while(1)
        {
    		
    	}
    }
  8. 编译测试

  9. 舵机转动的封装函数书写

    void lock(unsigned char mode)//舵机的工作模式0-上锁 1-开锁
    {
    
        if(mode==0)//0度
        {
           TIM_SetCompare1(TIM2, 500);//设置占空比
        }else if(mode==1)
        {
           TIM_SetCompare1(TIM2, 1500);//设置占空比
    
        }
    }

3.屏幕的移植

  1. 接线说明(VCC-3.3V SCL-PB3 SDA-PB5 RES-3.3V DC-PD3 CS-PD4 BLK-3.3V GND-记得共地)-推荐这么接线还有一点注意供电稳定

    例程位置

    其中里面有LCD接线-LCD屏幕实验教程

  2. 双击打开spi_lcd这个例程,编译运行,发现错误将错误直接注释掉即可,下载测试(查看现象是否是符合预期)

  3. 创建一个Driver文件夹用于存放移植过来的屏幕驱动(如图所示)

    添加方式为:右键点击工程->添加已存在目录->Driver文件夹

  4. 在Driver文件夹中右键新建.c和.h文件(lcd.c和.h)

  5. 将例程的lcd.c和.h进行cv到我们自己创建的文件中

  6. 添加文件路径

    右键user文件夹(属性)->C/C++ General->路径和符号->添加->勾选->工作空间->选择Driver文件夹->应用并关闭

  7. 将例程的#include "font_ascii_16x8.h"这个文件的代码也复制到我们的Driver文件夹中(注意新建这个.h文件)

  8. 主文件的书写

    #include "lcd.h"//头文件定义书写-这个放到上方的头文件定义位置
    //中间省略
    
    int main(void)
    {
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
    	SystemCoreClockUpdate();//时钟配置
    	//USART_Printf_Init(115200);//串口1初始化
    	Delay_Init();//延时函数初始化
    	TIM2_PWM_Init();//定时器初始化
    	GPIO_Pwm_Init();//GPIO初始化
    	TIM_SetCompare1(TIM2, 1500);//设置占空比
    	LCD_Init();//LCD初始化
    	LCD_Fill(0, 0, 127, 127, WHITE);//先将屏幕清空为白色
    	LCD_Fill(10,10,20,20,RED);//再显示我们的红色小方块
    	while(1)
        {
    		
    	}
    }
  9. 编译下载

  10. 屏幕上绘制进度条(这个函数可以放置在屏幕清空后进行)

    	unsigned char i=0;
    	while(i<128)
    	{
    	        LCD_DrawLine(i, 100, i, 127, RED);//绘制一条红色的随时间增长的红线(可以制作为进度条)
    	        i++;
    	        Delay_Ms(20);
    	}
  11. 模块资料里面的打开文字取模软件(PCtoLCD2002)->点击齿轮->设置如下(注意设置字宽和字高)

  12. 生成自己想要的字模(在生成字模旁边就是文字输入框)->复制->粘贴至font_ascii_16x8.h文件中汉字字模位置(格式与我上面相同即可)

  13. 主函数书写(注意我们字的大小是16,所以使用LCD_Show_Chinese这个API需要注意字的大小)

    int main(void)
    {
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
    	SystemCoreClockUpdate();//时钟配置
    	//USART_Printf_Init(115200);//串口1初始化
    	Delay_Init();//延时函数初始化
    	TIM2_PWM_Init();//定时器初始化
    	GPIO_Pwm_Init();//GPIO初始化
    	TIM_SetCompare1(TIM2, 1500);//设置占空比
    	LCD_Init();//LCD初始化
    	LCD_Fill(0, 0, 127, 127, WHITE);//先将屏幕清空为白色
    	unsigned char i=0;
    	while(i<128)
    	{
    	        LCD_DrawLine(i, 100, i, 127, RED);//绘制一条红色的随时间增长的红线(可以制作为进度条)
    	        i++;
    	        Delay_Ms(20);
    	}
    	LCD_Show_Chinese(0, 0, "门锁状态:上锁", RED, WHITE, 16, 0);
    	LCD_Show_Chinese(0,30,"输入密码",RED,WHITE,16,0);
    	while(1)
        {
    		
    	}
    }
  14. 大家可以根据自己的想法进行DIY即可(若有不知到的API可以将代码甩给AI进行辅助开发)

  15. 创建两个文件pic.c和.h并在主文件中进行引用-这个是放置图片取模软件取下来的图

    #include "pic.h"//照片头文件
  16. 这个工程文件的完整代码我放入百度网盘,gitee,github中,可以直接使用我的pic.c和.h代码

  17. 这是我的LCD主文件操作(其中LCD_ShowPicture的api使用如图所示)

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
	SystemCoreClockUpdate();//时钟配置
	//USART_Printf_Init(115200);//串口1初始化
	Delay_Init();//延时函数初始化
	TIM2_PWM_Init();//定时器初始化
	GPIO_Pwm_Init();//GPIO初始化
	TIM_SetCompare1(TIM2, 1500);//设置占空比
	LCD_Init();//LCD初始化
	LCD_Fill(0, 0, 127, 127, WHITE);
	LCD_ShowPicture(0, 0, 128, 128, gImage_1);
	unsigned char i=0;
	while(i<128)
	{
	        LCD_DrawLine(i, 0, i, 10, RED);//绘制一条红色的随时间增长的红线(可以制作为进度条)
	        i++;
	        Delay_Ms(20);
	}
	/*进度条走完后,首页显示*/


	LCD_ShowPicture(0, 0, 128, 128, gImage_2);
	LCD_Show_Chinese(0, 0, "门锁状态:上锁", RED, WHITE, 16, 0);
	LCD_Show_Chinese(0,30,"输入密码",RED,WHITE,16,0);
	while(1)
    {
		
	}
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐