1.采样结果、LED跟随闪烁:
2.程序:
userpinmux.h
/*
* Userpinmux.h
*
* Created on: 2023年7月5日
* Author: 86195
*/
#ifndef USER_USERPINMUX_H_
#define USER_USERPINMUX_H_
#include "debug.h"
#define ERR_PRINT(x) printf("Error [%d] at line [%d] in function [%s] \n\r",x,__LINE__,__FUNCTION__)
//定义主从机
#define I2C_MODE_HOST 0
#define I2C_MODE_SLAVE 1
//I2C 通信模式选择
//#define I2C_MODE I2C_MODE_HOST
#define I2C_MODE I2C_MODE_SLAVE
//I2C
#define Buf_Size_2 6
#define RXAdderss 0x02
#define TxAdderss 0x02
//LCD1602
#define DATA_1602 0X00FF//0000000011111111(0-7)管脚选中
#define RS GPIO_Pin_12
#define RW GPIO_Pin_4
#define EN GPIO_Pin_3
#define WRITE_DATA 1
#define WRITE_CMD 0
#define Buf_Size 32
#define RS_HIGH GPIO_SetBits(GPIOB, RS)
#define RS_LOW GPIO_ResetBits(GPIOB, RS)
#define RW_HIGH GPIO_SetBits(GPIOB, RW)
#define RW_LOW GPIO_ResetBits(GPIOB, RW)
#define EN_HIGH GPIO_SetBits(GPIOB, EN)
#define EN_LOW GPIO_ResetBits(GPIOB, EN)
//system
#define NULL_SYSTEM 0
#define FreeRTOS 1
//FreeRTOS
#define TASK1_usstackdepth 200
#define TASK2_usstackdepth 200
#define TASK1_priority 5
#define TASK2_priority 5
//显示屏12864
#define LCD_CS_H() GPIO_WriteBit(GPIOA, GPIO_Pin_1, 1)
#define LCD_CS_L() GPIO_WriteBit(GPIOA, GPIO_Pin_1, 0)
#define LCD_RS_H() GPIO_WriteBit(GPIOA, GPIO_Pin_3, 1)
#define LCD_RS_L() GPIO_WriteBit(GPIOA, GPIO_Pin_3, 0)
#define LCD_RES_H() GPIO_WriteBit(GPIOA, GPIO_Pin_2, 1)
#define LCD_RES_L() GPIO_WriteBit(GPIOA, GPIO_Pin_2, 0)
#define LCD_SDA_L() GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0)
#define LCD_SDA_H() GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1)
#define LCD_CLK_L() GPIO_WriteBit(GPIOA, GPIO_Pin_5, 0)
#define LCD_CLK_H() GPIO_WriteBit(GPIOA, GPIO_Pin_5, 1)
#define LCD_Delayms(x) Delay_Ms(x)
#define REG_DATA 1
#define REG_CMD 0
//test_of_cmd 每做一次更新屏蔽上一层
#define cmd_status_board 8
#define cmd_status_board_2 9
//1:外部中断;
//2:定时器中断
//3.DMA_存储器到存储器
//4.I2C-OLED
//5.I2C-24C04
//6.主从机收发的I2C
//7.LCD1602
//8.I2C_UC1701
//9.ADC+DMA
#define operating_system_enabled FreeRTOS
typedef struct {
u8 cmd_lcd1602;
u8 size_lcd1602;
u8* data;
} LCD_InitTypeDef;
void pinmux_init();
void EXTI15_10_INIT(void);
void TIM3_Int_Init(u16 arr, u16 psc);
//比较字符,若全相同返回1,任一不同返回0;
u8 BufCmp(u32 *buf1, u32 *buf2, u16 buflength);
void DMA1_CH3_Init(void);
void setup_DMA();
void I2C_Init_USER(u32 bound, u16 address); //I2C初始化设置
void I2C_INIT_USER_INIT(void); //I2C初始化
void I2C_WRITE_ONE_BYTE(u16 writeaddress, u8 data_write); //I2C写一个字
void I2C_WRITE_CMD(unsigned char I2C_COMMAND); //I2C写指令
void I2C_WRITE_DATA(unsigned char I2C_DATA); //I2C写数据
void OLED_INIT(); //oled初始化
void I2C_OLED_SETPOS(unsigned char X, unsigned char Y); //oled光标设置
void I2C_OLED_FILL(unsigned char FILL_DATA); //oled全屏
void I2C_OLED_CLEARSCREEN(); //OLED清屏
void I2C_OLED_ON(void); //OLED开机
void I2C_OLED_SLEEP(void); //oled休眠
void I2C_OLED_SHOW_STRING(unsigned char X, unsigned char Y,
unsigned char OLED_Str[], unsigned char T_Size); //OLED显示字符串
void I2C_OLED_SHOW_CHINESE(unsigned char X, unsigned char Y, unsigned char N); //显示中文
void I2C_OLED_DRAW(unsigned char X, unsigned char Y, unsigned char Z,
unsigned char Q, unsigned char picture_BMP[]); //显示位图
void I2C_Init_USER_7bit(u32 bound, u16 address);
void I2C_HOST();
void I2C_SLAVE();
void line8_LCD1602_USERINIT();
void line8_LCD1602_WRITE_CMD_DATA(u8 cmd, u8 data_cmd);
void line8_LCD1602_Write_Init(void);
void line8_LCD1602_OPEN();
void line8_LCD1602_SHUT();
void line8_LCD1602_DISPLAY(LCD_InitTypeDef LCD_INIT);
void GPIO_SYSTEM_INIT(void);
void MULTITASKING_TASKS1(void *pvParameters);
void MULTITASKING_TASKS2(void *pvParameters);
void MULTITASKING_TASKS_INIT();
void LCD_Init(void);
void LCD_Clear(void);
void LCD_DispStr8x16(uint8_t _ucPage,u_int8_t _ucColumn,char *str);
void LCD_DispNum(u_int8_t _ucPage,u_int8_t _ucColumn,u_int16_t num,u_int8_t _ucLenth);
void display();
void ADC_INIT_USER(void);
void ADC_VAL();
u16 ADC_DATAOPER_AVERAGE(u16 *buf,u8 times);
void DMA_TX_INIT(DMA_Channel_TypeDef *DMA_CHANNEL_X, u32 PPADDRESS, u32 MEMADDRESS, u16 BUFSIZE);
void ADC_PINMUX_INIT();
#endif /* USER_USERPINMUX_H_ */
userpinmux.c
#if cmd_status_board==9|cmd_status_board_2==9
void ADC_INIT_USER(void) {
ADC_InitTypeDef ADC_INIT;
GPIO_InitTypeDef GPIO_INIT_9;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1
RCC_ADCCLKConfig(RCC_PCLK2_Div8); //分频
GPIO_INIT_9.GPIO_Pin = GPIO_Pin_0;
GPIO_INIT_9.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_INIT_9); //配置模拟输入GPIOPB0
ADC_DeInit(ADC1); //重置ADC1寄存器
ADC_INIT.ADC_Mode = ADC_Mode_Independent;//独立模式
ADC_INIT.ADC_ScanConvMode = DISABLE;//单通道
ADC_INIT.ADC_ContinuousConvMode = ENABLE;//连续扫描
ADC_INIT.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//无外部触发
ADC_INIT.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
ADC_INIT.ADC_NbrOfChannel = 1;//通道数
ADC_Init(ADC1, &ADC_INIT);//初始化
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);//开启复位校准
while(ADC_GetResetCalibrationStatus(ADC1));//等待校准完成
ADC_StartCalibration(ADC1);//开启ADC校准
while(ADC_GetCalibrationStatus(ADC1));//等待ADC校准完成
}
void ADC_VAL()
{
u8 IRetVal;
ADC_RegularChannelConfig(ADC1, ADC_Channel_8,1, ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
IRetVal=ADC_GetSoftwareStartConvStatus(ADC1);
if (IRetVal==RESET)
{
ERR_PRINT("ADC_SOFTWARESTARTCONVCMD HAVEN'T SET");
}
}
u16 ADC_DATAOPER_AVERAGE(u16 *buf,u8 times)
{
u32 temp_val=0;
u8 t;
u16 val;
for(t=0;t<times;t++)
{
temp_val+=buf[t];
}
val=temp_val/times;
return val;
}
void DMA_TX_INIT(DMA_Channel_TypeDef *DMA_CHANNEL_X, u32 PPADDRESS, u32 MEMADDRESS, u16 BUFSIZE)
{
DMA_InitTypeDef DMA_INIT2;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能一个时钟
DMA_DeInit(DMA_CHANNEL_X);//重置寄存器
DMA_INIT2.DMA_PeripheralBaseAddr=PPADDRESS;//不开启外设地址。?
DMA_INIT2.DMA_MemoryBaseAddr=MEMADDRESS;//内存地址
DMA_INIT2.DMA_DIR=DMA_DIR_PeripheralSRC;//外设到内存
DMA_INIT2.DMA_BufferSize=BUFSIZE;//通道缓存大小
DMA_INIT2.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设寄存器地址不递增
DMA_INIT2.DMA_MemoryInc=DMA_MemoryInc_Enable;//内存地址递增
DMA_INIT2.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;//16位外设
DMA_INIT2.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;//16为内存
DMA_INIT2.DMA_Mode=DMA_Mode_Circular;//循环
DMA_INIT2.DMA_Priority=DMA_Priority_VeryHigh;//最高优先级
DMA_INIT2.DMA_M2M=DMA_M2M_Disable;//不开启内存到内存
DMA_Init(DMA_CHANNEL_X, &DMA_INIT2);//初始化DMA
DMA_Cmd(DMA_CHANNEL_X, ENABLE);//使能DMA
}
void ADC_PINMUX_INIT()
{
u16 TxBuf[10];
u16 adc_average;
ADC_INIT_USER();
DMA_TX_INIT(DMA1_Channel1,(u32)&ADC1->RDATAR,(u32)TxBuf,10);
ADC_VAL();
while(1)
{
Delay_Ms(100);
adc_average=ADC_DATAOPER_AVERAGE(TxBuf,10);
printf("vcc:%04dmV\r\n",(adc_average*3300)/4096);
}
}
#endif
//OS:FreeRTOS
#if operating_system_enabled==FreeRTOS
void GPIO_SYSTEM_INIT_2(void) {
GPIO_InitTypeDef GPIO_INIT_7;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_INIT_7.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_3;
GPIO_INIT_7.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_INIT_7.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_INIT_7);
}
void MULTITASKING_TASKS1(void *pvParameters) {
printf("TASK1: LED1!\r\n");
while(1)
{
// GPIO_SetBits(GPIOA, GPIO_Pin_1);
// vTaskDelay(250);
// GPIO_ResetBits(GPIOA, GPIO_Pin_1);
// vTaskDelay(250);
// clear_screen();
// display();
// vTaskDelay(10);
ADC_PINMUX_INIT();
}
}
void MULTITASKING_TASKS2(void *pvParameters) {
printf("TASK2: LED2!\r\n");
while(1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_3);
vTaskDelay(500);
GPIO_SetBits(GPIOB, GPIO_Pin_3);
vTaskDelay(500);
}
}
void MULTITASKING_TASKS_INIT(void) {
GPIO_SYSTEM_INIT_2();
/* create two task */
xTaskCreate((TaskFunction_t) MULTITASKING_TASKS1,
(const char*) "pcnames_task1", (uint16_t) TASK1_usstackdepth,
(void*) NULL, (UBaseType_t) TASK1_priority,
(TaskHandle_t*) &Task2Task_Handler);
xTaskCreate((TaskFunction_t) MULTITASKING_TASKS2,
(const char*) "pcnames_task2", (uint16_t) TASK2_usstackdepth,
(void*) NULL, (UBaseType_t) TASK2_priority,
(TaskHandle_t*) &Task1Task_Handler);
vTaskStartScheduler();
}
#endif
//void pinmux_init() {
// GPIO_InitTypeDef GPIO_INIT_1;
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// GPIO_INIT_1.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
// GPIO_INIT_1.GPIO_Mode = GPIO_Mode_Out_PP; //设置成推挽输出
// GPIO_INIT_1.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_Init(GPIOB, &GPIO_INIT_1);
// GPIO_SetBits(GPIOB, GPIO_Pin_4);
//}
#endif /* USER_USERPINMUX_C_ */
setup()
void setup() {
//*******系统默认**********//
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Delay_Init();
USART_Printf_Init(115200);
//*************************//
MULTITASKING_TASKS_INIT();
}
3.后续可以做的拓展:
预留了显示屏幕的函数,准备加入示波显示功能。
对于CH32V208,还可以考虑蓝牙传输数据的功能
后续还需要对各种错误做补充,将开发板出现的错误用串口打印出来
#define ERR_PRINT(x) printf("Error [%d] at line [%d] in function [%s] \n\r",x,__LINE__,__FUNCTION__)
就是这句话。
最好要是可以的话需要做一个typedef enum
类似这样:
typedef enum{
STATUS_BIT_NWP_INIT = 0, // If this bit is set: Network Processor is
// powered up
STATUS_BIT_CONNECTION, // If this bit is set: the device is connected to
// the AP or client is connected to device (AP)
STATUS_BIT_IP_LEASED, // If this bit is set: the device has leased IP to
// any connected client
STATUS_BIT_IP_AQUIRED, // If this bit is set: the device has acquired an IP
STATUS_BIT_SMARTCONFIG_START, // If this bit is set: the SmartConfiguration
// process is started from SmartConfig app
STATUS_BIT_P2P_DEV_FOUND, // If this bit is set: the device (P2P mode)
// found any p2p-device in scan
STATUS_BIT_P2P_REQ_RECEIVED, // If this bit is set: the device (P2P mode)
// found any p2p-negotiation request
STATUS_BIT_CONNECTION_FAILED, // If this bit is set: the device(P2P mode)
// connection to client(or reverse way) is failed
STATUS_BIT_PING_DONE // If this bit is set: the device has completed
// the ping operation
}e_StatusBits;