赞
踩
差不多就是这样了,有这样的逻辑写还是很简单的,无脑if
首先配置打开编码器捕获的定时器
我这里打开了2,3,4,5定时器,做编码器捕获,中断优先级为0,最高
之后打开普通定时器6开启低于这4个编码器一级的中断,用于计算pid
还有开启定时器8打开4个pwm通道
接下来配置8个输出引脚给每个电机各两个,可自己设置,按我的来就不用改代码了
还有uart通讯口要打开
记得打开uart中断优先最高级0
还有oled的i2c
最后看所有的中断
openmvuar的引脚
接下来加入代码,为方便直接再main.c中插入
uint8_t USART1_RX_BUFF[USART1_REC_LENGTH];//接收缓冲,最大USART_REC_LEN个字节. uint16_t USART1_RX_ST=0;//接收状态标记//bit15:接收完成标志,bit14~0:接收到的有效字节数目 uint8_t USART1_Data;//当前串口中断接收的1个字节数据的缓存 int cx,cy,cw,ch; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//串口中断回调函数 { if(huart ==&huart1) { if((USART1_RX_ST&0x8000)==0)//接收未完成 { if(USART1_Data==0x5B)//接收到了0x5A { USART1_RX_ST|=0x8000; //接收完成了,将USART1_RX_STA中的bit15(15位)置1 } else { USART1_RX_BUFF[USART1_RX_ST&0X7FFF]=USART1_Data; //将收到的数据放入数组, USART1_RX_ST++; //数据长度计数加1 if(USART1_RX_ST>(USART1_REC_LENGTH-1))USART1_RX_ST=0;//接收数据错误,重新开始接收 } } HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_Data,1); //因为每执行完一次中断回调函数会将接收中断功能关闭,所以最后需要再开启接收中断 } }
在main.h中插入
extern UART_HandleTypeDef huart1;//声明USART1的HAL库结构体
#define USART1_REC_LENGTH 200//定义USART1最大接收字节数
extern uint8_t USART1_RX_BUFF[USART1_REC_LENGTH];//接收缓冲,最大USART_REC_LEN个字节.末字节为校验和
extern uint16_t USART1_RX_ST;//接收状态标记
extern uint8_t USART1_Data;//当前串口中断接收的1个字节数据的缓存
extern int cx;
extern int cy;
extern int cw;
extern int ch;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);//串口中断回调函数声明
这个我之前的博客有写过单个电机的pid,没懂得可以先参考
单个编码器电机pid
我使用的底盘驱动是tb6612,能插上四个编码器电机
代码如下
pid.c
#include "pid.h" #include "tim.h" #include "usart.h" #include "gpio.h" #include "main.h" #define Encoder_TIM_Handle2 htim2 #define Encoder_TIM_Handle3 htim3 #define Encoder_TIM_Handle4 htim4 #define Encoder_TIM_Handle5 htim5 #define Motor_MAX_Duty 2000 int a; typedef struct __PID_Increment_Struct { float Kp, Ki, Kd; //系数 float Error_Last1; //上次误差 float Error_Last2; //上次误差 float Out_Last; //上次输出 } PID_Increment_Struct; void motor11()//1正 { AIN1(1); AIN2(0);} void motor10()//1反 { AIN1(0); AIN2(1);} void motor21()//2正 { BIN1(0); BIN2(1);} void motor20()//2反 { BIN1(1); BIN2(0);} void motor31()//3正 { CIN1(0); CIN2(1);} void motor30()//3反 { CIN1(1); CIN2(0);} void motor40()//4正 { DIN1(0); DIN2(1);} void motor41()//4反 { DIN1(1); DIN2(0);} float Get_Speed1() { int16_t zj; float Speed = 0; zj = __HAL_TIM_GetCounter(&Encoder_TIM_Handle2); __HAL_TIM_SetCounter(&Encoder_TIM_Handle2, 0); Speed = (float)zj / (4 * 11 * 30) * 100 * 60; a=Speed; return Speed; // printf("%f\n",Speed);//输出转速 } float Get_Speed2() { int16_t zj; float Speed = 0; zj = __HAL_TIM_GetCounter(&Encoder_TIM_Handle3); __HAL_TIM_SetCounter(&Encoder_TIM_Handle3, 0); Speed = (float)zj / (4 * 11 * 30) * 100 * 60; return Speed; // printf("%f\n",Speed);//输出转速 } float Get_Speed3() { int16_t zj; float Speed = 0; zj = __HAL_TIM_GetCounter(&Encoder_TIM_Handle4); __HAL_TIM_SetCounter(&Encoder_TIM_Handle4, 0); Speed = (float)zj / (4 * 11 * 30) * 100 * 60; return Speed; // printf("%f\n",Speed);//输出转速 } float Get_Speed4() { int16_t zj; float Speed = 0; zj = __HAL_TIM_GetCounter(&Encoder_TIM_Handle5); __HAL_TIM_SetCounter(&Encoder_TIM_Handle5, 0); Speed = (float)zj / (4 * 11 * 30) * 100 * 60; return Speed; // printf("%f\n",Speed);//输出转速 } float PID_Increment(PID_Increment_Struct *PID, float Current, float Target) { float err, //误差 out, //输出 proportion, //比例 differential; //微分 err = (float)Target - (float)Current; //计算误差 proportion = (float)err - (float)PID->Error_Last1; //计算比例项 differential = (float)err - 2 * (float)PID->Error_Last1 + (float)PID->Error_Last2; //计算微分项 if((err<=40&&err>=1)||(err<=-1&&err>=-40)) out = (float)PID->Out_Last + (float)PID->Kp * proportion+(float)PID->Ki * err+ (float)PID->Kd * differential; //计算PID else //如果不if else,调试的时候如果单片机只是5v上电但电机没转,你接12v电源开电机,电机速度会拉满,这就不好了 out = (float)PID->Out_Last + (float)PID->Kp * proportion+(float)PID->Kd * differential; //计算PID // out = (float)PID->Out_Last + (float)PID->Kp * proportion+(float)PID->Ki * err+ (float)PID->Ki * err + (float)PID->Kd * differential; //计算PID PID->Error_Last2 = PID->Error_Last1; //更新上上次误差 PID->Error_Last1 = err; //更新误差 PID->Out_Last = out; //更新上此输出 return out; } void motor1(int16_t Speed) { if (Speed == 0) { __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_1,Motor_MAX_Duty+1 ); } else if (Speed > 0) { motor10(); __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_1,Speed); } else if (Speed < 0) { Speed *= -1; motor11(); __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_1,Speed); } } void motor2(int16_t Speed) { if (Speed == 0) { __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_2,Motor_MAX_Duty+1 ); } else if (Speed > 0) { motor20(); __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_2,Speed); } else if (Speed < 0) { Speed *= -1; motor21(); __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_2,Speed); } } void motor3(int16_t Speed) { if (Speed == 0) { __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_3,Motor_MAX_Duty+1 ); } else if (Speed > 0) { motor30(); __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_3,Speed); } else if (Speed < 0) { Speed *= -1; motor31(); __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_3,Speed); } } void motor4(int16_t Speed) { if (Speed == 0) { __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_4,Motor_MAX_Duty+1 ); } else if (Speed > 0) { motor40(); __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_4,Speed); } else if (Speed < 0) { Speed *= -1; motor41(); __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_4,Speed); } } PID_Increment_Struct PID_Speed = {5, 0, 0}; float Speed[4]={0,0,0,0}; float mb_speed_last; float set_speed[4]; float mb_speed[4]; int i; float mb_speed[4]; void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { // float Speed = 0; // float set_speed = 0; float s=cw*ch; if (htim == &htim2) { } else if (htim == &htim3) { } else if (htim == &htim4) { } else if (htim == &htim5) { } else if (htim == &htim6) { Speed[0] = Get_Speed1(); Speed[1] = Get_Speed2(); Speed[2] = Get_Speed3(); Speed[3] = Get_Speed4(); // mb_speed = (int16_t)PID_Increment(&PID_Speed, Speed , aa); if(cw>=10&&ch>=10) {mb_speed[0] = 0.012*(9000-s)-(162-cx); mb_speed[1] = 0.012*(9000-s)+(162-cx); mb_speed[2] = 0.012*(9000-s)+(162-cx); mb_speed[3] = 0.012*(9000-s)-(162-cx);} else {mb_speed[0] = 50; mb_speed[1] = -50; mb_speed[2] = -50; mb_speed[3] = 50;} for(i=0;i<4;i++) {set_speed[i] = PID_Increment(&PID_Speed, Speed[i], mb_speed[i]); if (set_speed[i]> 2000) set_speed[i] = 2000; else if (set_speed[i] < -2000) set_speed[i] = -2000; } motor1(set_speed[0]); motor2(set_speed[1]); motor3(set_speed[2]); motor4(set_speed[3]); // printf("%f,%f\r\n", Speed, mb_speed); // a=set_speed; // printf("%f,%f\r\n", angle, Speed); } }
pid.h
#ifndef __PID_H #define __PID_H #define AIN1(state) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,(GPIO_PinState)(state)) //IN1 #define AIN2(state) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,(GPIO_PinState)(state)) //IN2 #define BIN1(state) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,(GPIO_PinState)(state)) //IN1 #define BIN2(state) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,(GPIO_PinState)(state)) //IN2 #define CIN1(state) HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,(GPIO_PinState)(state)) //IN1 #define CIN2(state) HAL_GPIO_WritePin(GPIOC,GPIO_PIN_5,(GPIO_PinState)(state)) //IN2 #define DIN1(state) HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,(GPIO_PinState)(state)) //IN1 #define DIN2(state) HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,(GPIO_PinState)(state)) //IN2 extern int a; #endif
具体学习可以参考链接: link
oled.c
/* * oled.c * * Created on: 2022年7月24日 * Author: Unicorn_Li */ #include "oled.h" /********************************************************** * 初始化命令,根据芯片手册书写,详细步骤见上图以及注意事项 ***********************************************************/ uint8_t CMD_Data[]={ 0xAE, 0xD5, 0x80, 0xA8, 0x3F, 0xD3, 0x00, 0x40,0xA1, 0xC8, 0xDA, 0x12, 0x81, 0xCF, 0xD9, 0xF1, 0xDB, 0x40, 0xA4, 0xA6,0x8D, 0x14, 0xAF}; /** * @function: void OLED_Init(void) * @description: OLED初始化 * @return {*} */ void OLED_Init(void) { HAL_Delay(200); uint8_t i = 0; for(i=0; i<23; i++) { OLED_WR_CMD(CMD_Data[i]); } } /** * @function: void OLED_WR_CMD(uint8_t cmd) * @description: 向设备写控制命令 * @param {uint8_t} cmd 芯片手册规定的命令 * @return {*} */ void OLED_WR_CMD(uint8_t cmd) { HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100); } /** * @function: void OLED_WR_DATA(uint8_t data) * @description: 向设备写控制数据 * @param {uint8_t} data 数据 * @return {*} */ void OLED_WR_DATA(uint8_t data) { HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100); } /** * @function: void OLED_On(void) * @description: 更新显示 * @return {*} */ void OLED_On(void) { uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_CMD(0xb0+i); //设置页地址(0~7) OLED_WR_CMD(0x00); //设置显示位置—列低地址 OLED_WR_CMD(0x10); //设置显示位置—列高地址 for(n=0;n<128;n++) OLED_WR_DATA(1); } } /** * @function: OLED_Clear(void) * @description: 清屏,整个屏幕是黑色的!和没点亮一样!!! * @return {*} */ void OLED_Clear(void) { uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_CMD(0xb0+i); //设置页地址(0~7) OLED_WR_CMD(0x00); //设置显示位置—列低地址 OLED_WR_CMD(0x10); //设置显示位置—列高地址 for(n=0;n<128;n++) OLED_WR_DATA(0); } } /** * @function: void OLED_Display_On(void) * @description: 开启OLED显示 * @return {*} */ void OLED_Display_On(void) { OLED_WR_CMD(0X8D); //SET DCDC命令 OLED_WR_CMD(0X14); //DCDC ON OLED_WR_CMD(0XAF); //DISPLAY ON,打开显示 } /** * @function: void OLED_Display_Off(void) * @description: 关闭OLED显示 * @return {*} */ void OLED_Display_Off(void) { OLED_WR_CMD(0X8D); //SET DCDC命令 OLED_WR_CMD(0X10); //DCDC OFF OLED_WR_CMD(0XAE); //DISPLAY OFF,关闭显示 } /** * @function: void OLED_Set_Pos(uint8_t x, uint8_t y) * @description: 坐标设置 * @param {uint8_t} x,y * @return {*} */ void OLED_Set_Pos(uint8_t x, uint8_t y) { OLED_WR_CMD(0xb0+y); //设置页地址(0~7) OLED_WR_CMD(((x&0xf0)>>4)|0x10); //设置显示位置—列高地址 OLED_WR_CMD(x&0x0f); //设置显示位置—列低地址 } /** * @function: unsigned int oled_pow(uint8_t m,uint8_t n) * @description: m^n函数 * @param {uint8_t} m,n * @return {unsigned int} result */ unsigned int oled_pow(uint8_t m,uint8_t n) { unsigned int result=1; while(n--)result*=m; return result; } /** * @function: void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size,uint8_t Color_Turn) * @description: 在OLED12864特定位置开始显示一个字符 * @param {uint8_t} x字符开始显示的横坐标 * @param {uint8_t} y字符开始显示的纵坐标 * @param {uint8_t} chr待显示的字符 * @param {uint8_t} Char_Size待显示字符的字体大小,选择字体 16/12 * @param {uint8_t} Color_Turn是否反相显示(1反相、0不反相) * @return {*} */ void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size,uint8_t Color_Turn) { unsigned char c=0,i=0; c=chr-' ';//得到偏移后的值 if(x>128-1){x=0;y=y+2;} if(Char_Size ==16) { OLED_Set_Pos(x,y); for(i=0;i<8;i++) { if(Color_Turn) OLED_WR_DATA(~F8X16[c*16+i]); else OLED_WR_DATA(F8X16[c*16+i]); } OLED_Set_Pos(x,y+1); for(i=0;i<8;i++) { if(Color_Turn) OLED_WR_DATA(~F8X16[c*16+i+8]); else OLED_WR_DATA(F8X16[c*16+i+8]); } } else { OLED_Set_Pos(x,y); for(i=0;i<6;i++) { if(Color_Turn) OLED_WR_DATA(~F6x8[c][i]); else OLED_WR_DATA(F6x8[c][i]); } } } /** * @function: void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr, uint8_tChar_Size, uint8_t Color_Turn) * @description: 在OLED12864特定位置开始显示字符串 * @param {uint8_t} x待显示字符串的开始横坐标x:0~127 * @param {uint8_t} y待显示字符串的开始纵坐标 y:0~7,若选择字体大小为16,则两行数字之间需要间隔2,若选择字体大小为12,间隔1 * @param {uint8_t} *chr待显示的字符串 * @param {uint8_t} Char_Size待显示字符串的字体大小,选择字体 16/12,16为8X16,12为6x8 * @param {uint8_t} Color_Turn是否反相显示(1反相、0不反相) * @return {*} */ void OLED_ShowString(uint8_t x,uint8_t y,char*chr,uint8_t Char_Size, uint8_t Color_Turn) { uint8_t j=0; while (chr[j]!='\0') { OLED_ShowChar(x,y,chr[j],Char_Size, Color_Turn); if (Char_Size == 12) //6X8的字体列加6,显示下一个字符 x += 6; else //8X16的字体列加8,显示下一个字符 x += 8; if (x > 122 && Char_Size==12) //TextSize6x8如果一行不够显示了,从下一行继续显示 { x = 0; y++; } if (x > 120 && Char_Size== 16) //TextSize8x16如果一行不够显示了,从下一行继续显示 { x = 0; y++; } j++; } } /** * @function: void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2, Color_Turn) * @description: 显示数字 * @param {uint8_t} x待显示的数字起始横坐标,x:0~126 * @param {uint8_t} y待显示的数字起始纵坐标, y:0~7,若选择字体大小为16,则两行数字之间需要间隔2,若选择字体大小为12,间隔1 * @param {unsigned int} num:输入的数据 * @param {uint8_t } len:输入的数据位数 * @param {uint8_t} size2:输入的数据大小,选择 16/12,16为8X16,12为6x8 * @param {uint8_t} Color_Turn是否反相显示(1反相、0不反相) * @return {*} */ void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2, uint8_t Color_Turn) { uint8_t t,temp; uint8_t enshow=0; for(t=0;t<len;t++) { temp=(num/oled_pow(10,len-t-1))%10; if(enshow==0&&t<(len-1)) { if(temp==0) { OLED_ShowChar(x+(size2/2)*t,y,' ',size2, Color_Turn); continue; }else enshow=1; } OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2, Color_Turn); } } /** * @function: void OLED_Showdecimal(uint8_t x,uint8_t y,float num,uint8_t z_len,uint8_t f_len,uint8_t size2, uint8_t Color_Turn) * @description: 显示正负浮点数 * @param {uint8_t} x待显示的数字起始横坐标,x:0~126 * @param {uint8_t} y待显示的数字起始纵坐标, y:0~7,若选择字体大小为16,则两行数字之间需要间隔2,若选择字体大小为12,间隔1 * @param {float} num:输入的浮点型数据 * @param {uint8_t } z_ len:整数部分的位数 * @param {uint8_t } f_len: 小数部分的位数 * @param {uint8_t} size2:输入的数据大小,选择 16/12,16为8X16,12为6x8 * @param {uint8_t} Color_Turn是否反相显示(1反相、0不反相) * @return {*} */ void OLED_Showdecimal(uint8_t x,uint8_t y,float num,uint8_t z_len,uint8_t f_len,uint8_t size2, uint8_t Color_Turn) { uint8_t t,temp,i=0;//i为负数标志位 uint8_t enshow; int z_temp,f_temp; if(num<0) { z_len+=1; i=1; num=-num; } z_temp=(int)num; //整数部分 for(t=0;t<z_len;t++) { temp=(z_temp/oled_pow(10,z_len-t-1))%10; if(enshow==0 && t<(z_len-1)) { if(temp==0) { OLED_ShowChar(x+(size2/2)*t,y,' ',size2, Color_Turn); continue; } else enshow=1; } OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2, Color_Turn); } //小数点 OLED_ShowChar(x+(size2/2)*(z_len),y,'.',size2, Color_Turn); f_temp=(int)((num-z_temp)*(oled_pow(10,f_len))); //小数部分 for(t=0;t<f_len;t++) { temp=(f_temp/oled_pow(10,f_len-t-1))%10; OLED_ShowChar(x+(size2/2)*(t+z_len)+5,y,temp+'0',size2, Color_Turn); } if(i==1)//如果为负,就将最前的一位赋值‘-’ { OLED_ShowChar(x,y,'-',size2, Color_Turn); i=0; } } /** * @function: void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no, uint8_t Color_Turn) * @description: 在OLED特定位置开始显示16X16汉字 * @param {uint8_t} x待显示的汉字起始横坐标x: 0~112,两列汉字之间需要间隔16 * @param {uint8_t} y待显示的汉字起始纵坐标 y: 0~6 , 两行汉字之间需要间隔2 * @param {uint8_t} no待显示的汉字编号 * @param {uint8_t} Color_Turn是否反相显示(1反相、0不反相) * @return {*} */ void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no, uint8_t Color_Turn) { uint8_t t=0; OLED_Set_Pos(x,y); for(t=0;t<16;t++) { if (Color_Turn) OLED_WR_DATA(~Hzk[2*no][t]); //显示汉字的上半部分 else OLED_WR_DATA(Hzk[2*no][t]); //显示汉字的上半部分 } OLED_Set_Pos(x,y+1); for(t=0;t<16;t++) { if (Color_Turn) OLED_WR_DATA(~Hzk[2*no+1][t]); //显示汉字的上半部分 else OLED_WR_DATA(Hzk[2*no+1][t]);//显示汉字的上半部分 } } /** * @function: void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t * BMP,uint8_t Color_Turn) * @description: 在OLED特定区域显示BMP图片 * @param {uint8_t} x0图像开始显示横坐标 x0:0~127 * @param {uint8_t} y0图像开始显示纵坐标 y0:0~7 * @param {uint8_t} x1图像结束显示横坐标 x1:1~128 * @param {uint8_t} y1图像结束显示纵坐标 y1:1~8 * @param {uint8_t} *BMP待显示的图像数据 * @param {uint8_t} Color_Turn是否反相显示(1反相、0不反相) * @return {*} */ void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t * BMP,uint8_t Color_Turn) { uint32_t j = 0; uint8_t x = 0, y = 0; if(y1%8==0) y = y1/8; else y = y1/8 + 1; for(y=y0;y<y1;y++) { OLED_Set_Pos(x0,y); for(x=x0;x<x1;x++) { if (Color_Turn) OLED_WR_DATA(~BMP[j++]);//显示反相图片 else OLED_WR_DATA(BMP[j++]);//显示图片 } } } /** * @function: void OLED_HorizontalShift(uint8_t direction) * @description: 屏幕内容水平全屏滚动播放 * @param {uint8_t} direction LEFT 0x27 RIGHT 0x26 * @return {*} */ void OLED_HorizontalShift(uint8_t direction) { OLED_WR_CMD(0x2e);//停止滚动 OLED_WR_CMD(direction);//设置滚动方向 OLED_WR_CMD(0x00);//虚拟字节设置,默认为0x00 OLED_WR_CMD(0x00);//设置开始页地址 OLED_WR_CMD(0x07);//设置每个滚动步骤之间的时间间隔的帧频 // 0x00-5帧, 0x01-64帧, 0x02-128帧, 0x03-256帧, 0x04-3帧, 0x05-4帧, 0x06-25帧, 0x07-2帧, OLED_WR_CMD(0x07);//设置结束页地址 OLED_WR_CMD(0x00);//虚拟字节设置,默认为0x00 OLED_WR_CMD(0xff);//虚拟字节设置,默认为0xff OLED_WR_CMD(0x2f);//开启滚动-0x2f,禁用滚动-0x2e,禁用需要重写数据 } /** * @function: void OLED_Some_HorizontalShift(uint8_t direction,uint8_t start,uint8_t end) * @description: 屏幕部分内容水平滚动播放 * @param {uint8_t} direction LEFT 0x27 RIGHT 0x26 * @param {uint8_t} start 开始页地址 0x00~0x07 * @param {uint8_t} end 结束页地址 0x01~0x07 * @return {*} */ void OLED_Some_HorizontalShift(uint8_t direction,uint8_t start,uint8_t end) { OLED_WR_CMD(0x2e);//停止滚动 OLED_WR_CMD(direction);//设置滚动方向 OLED_WR_CMD(0x00);//虚拟字节设置,默认为0x00 OLED_WR_CMD(start);//设置开始页地址 OLED_WR_CMD(0x07);//设置每个滚动步骤之间的时间间隔的帧频,0x07即滚动速度2帧 OLED_WR_CMD(end);//设置结束页地址 OLED_WR_CMD(0x00);//虚拟字节设置,默认为0x00 OLED_WR_CMD(0xff);//虚拟字节设置,默认为0xff OLED_WR_CMD(0x2f);//开启滚动-0x2f,禁用滚动-0x2e,禁用需要重写数据 } /** * @function: void OLED_VerticalAndHorizontalShift(uint8_t direction) * @description: 屏幕内容垂直水平全屏滚动播放 * @param {uint8_t} direction 右上滚动 0x29 * 左上滚动 0x2A * @return {*} */ void OLED_VerticalAndHorizontalShift(uint8_t direction) { OLED_WR_CMD(0x2e);//停止滚动 OLED_WR_CMD(direction);//设置滚动方向 OLED_WR_CMD(0x01);//虚拟字节设置 OLED_WR_CMD(0x00);//设置开始页地址 OLED_WR_CMD(0x07);//设置每个滚动步骤之间的时间间隔的帧频,即滚动速度 OLED_WR_CMD(0x07);//设置结束页地址 OLED_WR_CMD(0x01);//垂直滚动偏移量 OLED_WR_CMD(0x00);//虚拟字节设置,默认为0x00 OLED_WR_CMD(0xff);//虚拟字节设置,默认为0xff OLED_WR_CMD(0x2f);//开启滚动-0x2f,禁用滚动-0x2e,禁用需要重写数据 } /** * @function: void OLED_DisplayMode(uint8_t mode) * @description: 屏幕内容取反显示 * @param {uint8_t} direction ON 0xA7 , * OFF 0xA6 默认此模式,设置像素点亮 * @return {*} */ void OLED_DisplayMode(uint8_t mode) { OLED_WR_CMD(mode); } /** * @function: void OLED_IntensityControl(uint8_t intensity) * @description: 屏幕亮度调节 * @param {uint8_t} intensity 0x00~0xFF,RESET=0x7F * @return {*} */ void OLED_IntensityControl(uint8_t intensity) { OLED_WR_CMD(0x81); OLED_WR_CMD(intensity); } /* * oledfont.c * * Created on: Jul 24, 2022 * Author: Unicorn_Li */ //#include "oledfont.h" //8*6 ASCII字符集点阵 const unsigned char F6x8[][6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// ! 0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// " 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// # 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $ 0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// % 0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// & 0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// ' 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// ( 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// ) 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// * 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// + 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// , 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// - 0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// . 0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// / 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1 0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4 0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6 0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7 0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9 0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// : 0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ; 0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// < 0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// = 0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// > 0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ? 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @ 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R 0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W 0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X 0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y 0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [ 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ] 0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _ 0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// ' 0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b 0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d 0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n 0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r 0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w 0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines }; //16*8 ASCII字符集点阵 const unsigned char F8X16[]= { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//sp /0 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! /1 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" /2 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# /3 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ /4 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% /5 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& /6 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' /7 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( /8 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) /9 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* /10 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ /11 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, /12 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- /13 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. /14 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// /15 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 /16 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 /17 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 /18 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 /19 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 /20 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 /21 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 /22 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 /23 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 /24 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 /25 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: /26 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; /27 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< /28 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= /29 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> /30 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? /31 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ /32 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A /33 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B /34 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C /35 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D /36 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E /37 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F /38 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G /39 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H /40 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I /41 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J /42 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K /43 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L /44 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M /45 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N /46 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O /47 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P /48 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q /49 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R /50 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S /51 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T /52 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U /53 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V /54 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W /55 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X /56 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y /57 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z /58 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ /59 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ /60 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] /61 0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ /62 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ /63 0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` /64 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a /65 0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b /66 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c /67 0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d /68 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e /69 0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f /70 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g /71 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h /72 0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i /73 0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j /74 0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k /75 0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l /76 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m /77 0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n /78 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o /79 0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p /80 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q /81 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r /82 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s /83 0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t /84 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u /85 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v /86 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w /87 0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x /88 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y /89 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z /90 0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ /91 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} /92 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00};//| /93 //部分汉字 阴码,列行式,逆向 const unsigned char Hzk[][32]= { {0x40,0x22,0x14,0x08,0xF4,0x02,0x00,0xF8,0x08,0x08,0xFF,0x08,0x08,0xF8,0x00,0x00}, {0x08,0x44,0x82,0x41,0x3F,0x00,0x20,0x63,0x21,0x21,0x3F,0x21,0x29,0x33,0x60,0x00},/*"独",0*/ {0x20,0x10,0xE8,0x24,0x27,0x24,0x24,0xE4,0x24,0x34,0x2C,0x20,0xE0,0x00,0x00,0x00}, {0x80,0x60,0x1F,0x09,0x09,0x09,0x09,0x7F,0x09,0x09,0x49,0x89,0x7F,0x00,0x00,0x00},/*"角",1*/ {0x00,0x00,0x7C,0x54,0x55,0x56,0x54,0x7C,0x54,0x56,0x55,0x54,0x7C,0x00,0x00,0x00}, {0x01,0x01,0x01,0xFD,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0xFD,0x01,0x01,0x01,0x00},/*"兽",2*/ }; //128*64图片 unsigned char BMP1[]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x40,0xE0,0xE0,0x60, 0x00,0x40,0x80,0x00,0x00,0x00,0x80,0x80,0x60,0x60,0x10,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x90,0xB2,0x66,0x6E,0xEC,0xC9,0x83,0x02,0x00,0x40,0x80, 0x00,0x0C,0x0C,0x01,0x03,0x07,0x0F,0x11,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x08,0x18,0x3B,0x37,0x66,0xEE,0xEE,0xCC,0x88,0x80,0x00,0x00, 0x01,0x02,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x0F,0x00,0x00,0x00,0x00,0x00, 0x00,0x3E,0x40,0x40,0x40,0x3E,0x00,0x7E,0x04,0x08,0x10,0x7E,0x00,0x7E,0x00,0x3C, 0x42,0x42,0x42,0x42,0x00,0x7E,0x42,0x42,0x42,0x7E,0x00,0x7E,0x04,0x08,0x10,0x7E,/*"C:\Users\HP\Desktop\UNICORN.BMP",0*/ };
oled.h
#ifndef OLED_OLED_H_ #define OLED_OLED_H_ #include "stm32f1xx_hal.h" //#include "oledfont.h" extern I2C_HandleTypeDef hi2c1; void OLED_WR_CMD(uint8_t cmd); void OLED_WR_DATA(uint8_t data); void OLED_Init(void); void OLED_Clear(void); void OLED_Display_On(void); void OLED_Display_Off(void); void OLED_Set_Pos(uint8_t x, uint8_t y); void OLED_On(void); void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2,uint8_t Color_Turn); void OLED_Showdecimal(uint8_t x,uint8_t y,float num,uint8_t z_len,uint8_t f_len,uint8_t size2, uint8_t Color_Turn); void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size,uint8_t Color_Turn); void OLED_ShowString(uint8_t x,uint8_t y,char*chr,uint8_t Char_Size,uint8_t Color_Turn); void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no,uint8_t Color_Turn); void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t * BMP,uint8_t Color_Turn); void OLED_HorizontalShift(uint8_t direction); void OLED_Some_HorizontalShift(uint8_t direction,uint8_t start,uint8_t end); void OLED_VerticalAndHorizontalShift(uint8_t direction); void OLED_DisplayMode(uint8_t mode); void OLED_IntensityControl(uint8_t intensity); extern const unsigned char F6x8[][6]; extern const unsigned char F8X16[]; extern const unsigned char Hzk[][32]; extern unsigned char BMP1[]; #endif /* OLED_OLED_H_ */
参考链接: link
import sensor, image, time,math,pyb from pyb import UART,LED import json import ustruct sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.skip_frames(time = 2000) sensor.set_auto_gain(False) # must be turned off for color tracking sensor.set_auto_whitebal(False) # must be turned off for color tracking red_threshold_01=(0, 89, 125, 13, -34, 84) clock = time.clock() uart = UART(3,115200) #定义串口3变量 uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters def find_max(blobs): #定义寻找色块面积最大的函数 max_size=0 for blob in blobs: if blob.pixels() > max_size: max_blob=blob max_size = blob.pixels() return max_blob def sending_data(cx,cy,cw,ch): global uart; #frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B]; #data = bytearray(frame) data = ustruct.pack("<bbhhhhb", #格式为俩个字符俩个短整型(2字节) 0x2C, #帧头1 0x12, #帧头2 int(cx), # up sample by 4 #数据1 int(cy), # up sample by 4 #数据2 int(cw), # up sample by 4 #数据1 int(ch), # up sample by 4 #数据2 0x5B) uart.write(data); #必须要传入一个字节数组 while(True): clock.tick() img = sensor.snapshot() blobs = img.find_blobs([red_threshold_01]) cx=0;cy=0; if blobs: max_b = find_max(blobs) #如果找到了目标颜色 cx=max_b[5] cy=max_b[6] cw=max_b[2] ch=max_b[3] img.draw_rectangle(max_b[0:4]) # rect img.draw_cross(max_b[5], max_b[6]) # cx, cy #sending_data(cx,cy,cw,ch) else: cx=0 cy=0 cw=0 ch=0 FH = bytearray([0x2C,0x12,cx,cy,cw,ch,0x5B]) uart.write(FH) print(cx,cy,cw,ch)
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_I2C1_Init(); MX_USART1_UART_Init(); MX_TIM2_Init(); MX_TIM3_Init(); MX_TIM4_Init(); MX_TIM5_Init(); MX_TIM6_Init(); MX_TIM8_Init(); /* USER CODE BEGIN 2 */ HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_Data,1); //开启串口1的接收中断 HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL); //开启编码器模式 HAL_TIM_Base_Start_IT(&htim2); HAL_TIM_Base_Start(&htim2); HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL); //开启编码器模式 HAL_TIM_Base_Start_IT(&htim3); HAL_TIM_Base_Start(&htim3); HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL); //开启编码器模式 HAL_TIM_Base_Start_IT(&htim4); HAL_TIM_Base_Start(&htim4); HAL_TIM_Encoder_Start(&htim5, TIM_CHANNEL_ALL); //开启编码器模式 HAL_TIM_Base_Start_IT(&htim5); HAL_TIM_Base_Start(&htim5); HAL_TIM_Base_Start_IT(&htim6); //开启定时器的中断 HAL_TIM_Base_Start(&htim6); HAL_TIM_Base_Start_IT(&htim8); HAL_TIM_Base_Start(&htim8); HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2); HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_3); HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_4); OLED_Init(); //OLED初始 OLED_Clear(); //清屏 OLED_ShowString(0,0,"uart",16,0);//正相显示8X16字符串 OLED_ShowString(1,3,"cx",16,0);//正相显示8X16字符串 OLED_ShowString(32,3,"cy",16,0);//正相显示8X16字符串 OLED_ShowString(64,3,"cw",16,0);//正相显示8X16字符串 OLED_ShowString(96,3,"ch",16,0);//正相显示8X16字符串 /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { // if(a<0) // a=-a; // OLED_ShowNum(0,0,a,4,16, 0);//正相显示5位8X16数字“6” if(USART1_RX_ST&0x8000) { if(USART1_RX_BUFF[0]==0x2c&& USART1_RX_BUFF[1]==0x12) { cx=USART1_RX_BUFF[2]; cy=USART1_RX_BUFF[3]; cw=USART1_RX_BUFF[4]; ch=USART1_RX_BUFF[5]; } OLED_ShowNum(0,6,cx,4,16, 0);//正相显示5位8X16数字“6” OLED_ShowNum(32,6,cy,4,16, 0);//正相显示5位8X16数字“6” OLED_ShowNum(64,6,cw,4,16, 0);//正相显示5位8X16数字“6” OLED_ShowNum(96,6,ch,4,16, 0);//正相显示5位8X16数字“6” USART1_RX_ST=0;//标志位清0,准备下次接收 } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
颜色追踪小车
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。