(*((void (*)(void))(*(unsigned long *)0x2c)))(); 是什么意思?

(((void ()(void))((unsigned long )0x2c)))(); 是什么意思?
在8962的boot_demo1中 (
((void (
)(void))(*(unsigned long *)0x2c)))(); 是什么意思?是把程序引导到地址为0X2C的位置?

这个语句会执行位于bootloader的SVC(软中断)异常服务例程,还是分解一下吧:

(*(unsigned long *)0x2c):将0x2C强制转化为unsigned long类型指针,并指向该地址所在的数据;

void (*)(void) :函数指针,指针名为空,该函数参数为空,返回值为空

(void ()(void))((unsigned long *)0x2c):将Flash地址0x2C中的内容强制转化为函数指针,该函数参数为空,返回值为空

(((void ()(void))(*(unsigned long *)0x2c)))();:调用函数,即开始从启动代码中的UpdateHandler标号处开始执行

/************************************************ // //TWKJ STM32开发板 // //作者: //版本:V1.0 //修改日期:2020/06/30 //程序功能:TFT彩屏显示方法 //V1.0 完成基本功能 ************************************************/ #include "my_lcd_spi_gui.h" #include "my_lcd_spi_font.h" /******************************************************************* * @name :void GUI_DrawPoint(u16 x,u16 y,u16 color) * @date :2018-08-09 * @function :draw a point in LCD screen * @parameters :x:the x coordinate of the point y:the y coordinate of the point color:the color value of the point * @retvalue :None ********************************************************************/ void GUI_DrawPoint(u16 x,u16 y,u16 color) { LCD_SetCursor(x,y);//设置光标位置 LCD_WriteData_16Bit(color); } /***************************************************************************** * @name :void TP_Draw_Big_Point(u16 x,u16 y,u16 color) * @date :2018-08-09 * @function :Draw a big point(2*2) * @parameters :x:Read x coordinate of the point y:Read y coordinate of the point color:the color value of the point * @retvalue :None ******************************************************************************/ void LCD_DrawPoint_big(u16 x,u16 y) { LCD_DrawPoint(x,y);//中心点 LCD_DrawPoint(x+1,y); LCD_DrawPoint(x,y+1); LCD_DrawPoint(x+1,y+1); } /******************************************************************* * @name :void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color) 填充一个矩形 * @function :fill the specified area * @parameters :sx:the bebinning x coordinate of the specified area sy:the bebinning y coordinate of the specified area ex:the ending x coordinate of the specified area ey:the ending y coordinate of the specified area color:the filled color value * @retvalue :None ********************************************************************/ void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color) { u16 i,j; u16 width=ex-sx+1;//得到填充的宽度 u16 height=ey-sy+1;//高度//**All notes can be deleted and modified**// for(i=0;i<height;i++) { for(j=0;j<width;j++) LCD_WriteData_16Bit(color);//写入数据 } LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口设置为全屏 } /******************************************************************* * @name :void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2) 绘制一条线 * @function :Draw a line between two points * @parameters :x1:the bebinning x coordinate of the line y1:the bebinning y coordinate of the line x2:the ending x coordinate of the line y2:the ending y coordinate of the line * @retvalue :None ********************************************************************/ void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2) { u16 t; int xerr=0,yerr=0,delta_x,delta_y,distance; int incx,incy,uRow,uCol; delta_x=x2-x1; //计算坐标增量 delta_y=y2-y1; uRow=x1; uCol=y1; if(delta_x>0)incx=1; //设置单步方向 else if(delta_x==0)incx=0;//垂直线 else {incx=-1;delta_x=-delta_x;} if(delta_y>0)incy=1; else if(delta_y==0)incy=0;//水平线 else{incy=-1;delta_y=-delta_y;} if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴 else distance=delta_y; for(t=0;t<=distance+1;t++ )//画线输出 { LCD_DrawPoint(uRow,uCol);//画点 //**All notes can be deleted and modified**// if(xerr>distance) { xerr-=distance; uRow+=incx; } if(yerr>distance) { yerr-=distance; uCol+=incy; } } } /***************************************************************************** * @name :void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2) 绘制一个矩形框 * @function :Draw a rectangle * @parameters :x1:the bebinning x coordinate of the rectangle y1:the bebinning y coordinate of the rectangle x2:the ending x coordinate of the rectangle y2:the ending y coordinate of the rectangle * @retvalue :None ******************************************************************************/ void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2) { LCD_DrawLine(x1,y1,x2,y1); LCD_DrawLine(x1,y1,x1,y2); LCD_DrawLine(x1,y2,x2,y2); LCD_DrawLine(x2,y1,x2,y2); } /***************************************************************************** * @name :void LCD_DrawFillRectangle(u16 x1, u16 y1, u16 x2, u16 y2) 填充一个矩形 * @function :Filled a rectangle * @parameters :x1:the bebinning x coordinate of the filled rectangle y1:the bebinning y coordinate of the filled rectangle x2:the ending x coordinate of the filled rectangle y2:the ending y coordinate of the filled rectangle * @retvalue :None ******************************************************************************/ void LCD_DrawRectangle_Fill(u16 x1, u16 y1, u16 x2, u16 y2) { LCD_Fill(x1,y1,x2,y2,FRONT_COLOR); } /***************************************************************************** * @name :void _draw_circle_8(int xc, int yc, int x, int y, u16 c) 圆绘制方法 * @function :8 symmetry circle drawing algorithm (internal call) * @parameters :xc:the x coordinate of the Circular center yc:the y coordinate of the Circular center x:the x coordinate relative to the Circular center y:the y coordinate relative to the Circular center c:the color value of the circle * @retvalue :None ******************************************************************************/ void _draw_circle_8(int xc, int yc, int x, int y, u16 c) { GUI_DrawPoint(xc + x, yc + y, c); GUI_DrawPoint(xc - x, yc + y, c); GUI_DrawPoint(xc + x, yc - y, c); GUI_DrawPoint(xc - x, yc - y, c); GUI_DrawPoint(xc + y, yc + x, c); GUI_DrawPoint(xc - y, yc + x, c); GUI_DrawPoint(xc + y, yc - x, c); GUI_DrawPoint(xc - y, yc - x, c); } /***************************************************************************** * @name :void gui_circle(int xc, int yc,u16 c,int r, int fill) 绘制一个圆 实心或空心 * @function :Draw a circle of specified size at a specified location * @parameters :xc:the x coordinate of the Circular center yc:the y coordinate of the Circular center r:Circular radius fill:1-filling,0-no filling * @retvalue :None ******************************************************************************/ void LCD_DrawCircle(int xc, int yc,int r, int fill) { int x = 0, y = r, yi, d; d = 3 - 2 * r; if (fill) { // 如果填充(画实心圆) while (x <= y) { for (yi = x; yi <= y; yi++) { _draw_circle_8(xc, yc, x, yi, FRONT_COLOR); } if (d < 0) { d = d + 4 * x + 6; } else { d = d + 4 * (x - y) + 10; y--; } x++; } } else { // 如果不填充(画空心圆) while (x <= y) { _draw_circle_8(xc, yc, x, y, FRONT_COLOR); if (d < 0) { d = d + 4 * x + 6; } else { d = d + 4 * (x - y) + 10; y--; } x++; } } } /***************************************************************************** * @name :void Draw_Triangel(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2) 绘制一个三角形框 * @function :Draw a triangle at a specified position * @parameters :x0:the bebinning x coordinate of the triangular edge y0:the bebinning y coordinate of the triangular edge x1:the vertex x coordinate of the triangular y1:the vertex y coordinate of the triangular x2:the ending x coordinate of the triangular edge y2:the ending y coordinate of the triangular edge * @retvalue :None ******************************************************************************/ void LCD_DrawTriangel(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2) { LCD_DrawLine(x0,y0,x1,y1); LCD_DrawLine(x1,y1,x2,y2); LCD_DrawLine(x2,y2,x0,y0); } static void _swap(u16 *a, u16 *b) { u16 tmp; tmp = *a; *a = *b; *b = tmp; } /***************************************************************************** * @name :void Fill_Triangel(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2) 绘制一个三角形框填充 * @function :filling a triangle at a specified position * @parameters :x0:the bebinning x coordinate of the triangular edge y0:the bebinning y coordinate of the triangular edge x1:the vertex x coordinate of the triangular y1:the vertex y coordinate of the triangular x2:the ending x coordinate of the triangular edge y2:the ending y coordinate of the triangular edge * @retvalue :None ******************************************************************************/ void LCD_DrawTriangel_Fill(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2) { u16 a, b, y, last; int dx01, dy01, dx02, dy02, dx12, dy12; long sa = 0; long sb = 0; if (y0 > y1) { _swap(&y0,&y1); _swap(&x0,&x1); } if (y1 > y2) { _swap(&y2,&y1); _swap(&x2,&x1); } if (y0 > y1) { _swap(&y0,&y1); _swap(&x0,&x1); } if(y0 == y2) { a = b = x0; if(x1 < a) { a = x1; } else if(x1 > b) { b = x1; } if(x2 < a) { a = x2; } else if(x2 > b) { b = x2; } LCD_Fill(a,y0,b,y0,FRONT_COLOR); return; } dx01 = x1 - x0; dy01 = y1 - y0; dx02 = x2 - x0; dy02 = y2 - y0; dx12 = x2 - x1; dy12 = y2 - y1; if(y1 == y2) { last = y1; } else { last = y1-1; } for(y=y0; y<=last; y++) { a = x0 + sa / dy01; b = x0 + sb / dy02; sa += dx01; sb += dx02; if(a > b) { _swap(&a,&b); } LCD_Fill(a,y,b,y,FRONT_COLOR); } sa = dx12 * (y - y1); sb = dx02 * (y - y0); for(; y<=y2; y++) { a = x1 + sa / dy12; b = x0 + sb / dy02; sa += dx12; sb += dx02; if(a > b) { _swap(&a,&b); } LCD_Fill(a,y,b,y,FRONT_COLOR); } } /***************************************************************************** * @name :void Gui_Drawbmp16(u16 x,u16 y,const unsigned char *p) * @date :2018-08-09 * @function :Display a 16-bit BMP image * @parameters :x:the bebinning x coordinate of the BMP image y:the bebinning y coordinate of the BMP image p:the start address of image array * @retvalue :None ******************************************************************************/ void GUI_Drawbmp16(u16 x,u16 y,const u8 *p) //显示40*40 QQ图片 { int i; unsigned char picH,picL; LCD_SetWindows(x,y,x+40-1,y+40-1);//窗口设置 for(i=0;i<40*40;i++) { picL=*(p+i*2);//数据低位在前 picH=*(p+i*2+1); LCD_WriteData_16Bit(picH<<8|picL); } LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复显示窗口为全屏 } /***************************************************************************** * @name :void LCD_ShowString(u16 x,u16 y,u8 size,u8 *p,u8 mode) 显示遗传英文字符 只限英文 * @function :Display English string * @parameters :x:the bebinning x coordinate of the English string y:the bebinning y coordinate of the English string p:the start address of the English string size:the size of display character mode:0-no overlying,1-overlying * @retvalue :None ******************************************************************************/ void LCD_JustString(u16 x,u16 y,char *p,u8 size) { while((*p<='~')&&(*p>=' '))//判断是不是非法字符! { if(x>(lcddev.width-1)||y>(lcddev.height-1)) return; LCD_ShowChar(x,y,*p,size,false); x+=size/2; p++; } } /***************************************************************************** * @name :u32 mypow(u8 m,u8 n) * @date :2018-08-09 * @function :get the nth power of m (internal call) * @parameters :m:the multiplier n:the power * @retvalue :the nth power of m ******************************************************************************/ u32 mypow(u8 m,u8 n) { u32 result=1; while(n--)result*=m; return result; } /***************************************************************************** * @name :void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size) * @date :2018-08-09 * @function :Display number * @parameters :x:the bebinning x coordinate of the number y:the bebinning y coordinate of the number num:the number(0~4294967295) len:the length of the display number size:the size of display number * @retvalue :None ******************************************************************************/ void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size) { u8 t,temp; u8 enshow=0; for(t=0;t<len;t++) { temp=(num/mypow(10,len-t-1))%10; if(enshow==0&&t<(len-1)) { if(temp==0) { LCD_ShowChar(x+(size/2)*t,y,' ',size,false); continue; }else enshow=1; } LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,false); } } //计算汉字字模的大小(字节数) u8 My_Font_GetCodeSize_CH(u8 charSize) { return charSize*(charSize/8 + (charSize%8?1:0)); } //计算ASCII字模的大小(字节数) u8 My_Font_GetCodeSize_ASCII(u8 charSize) { //**All notes can be deleted and modified**// return charSize*(charSize/8 + (charSize%8?1:0))*2; } void LCD_ScanLine_Byte(u16 x, u16 y, u8 *charPtr,u8 pointCount,bool overlap) { u8 i; if(pointCount>8) { pointCount = 8; } for(i=0;i<pointCount;i++) { // if((*charPtr)&(0x01<<i))//逆向扫描 if(((*charPtr)&(0x80>>i)))//顺向扫描 { if(overlap) { LCD_DrawPoint(x,y);//画一个点 } else { LCD_WriteData_16Bit(FRONT_COLOR); } } else { if(!overlap) { LCD_WriteData_16Bit(BACK_COLOR); } } x++; } } //显示字符或图片取模后的数据,如自定义特殊字符 void LCD_DrawMatrixCode(u16 x, u16 y, u8 width,u8 high,u8 *charPtr,bool overlap) { u8 i,scanPointCount; u16 x0 = x; LCD_SetWindows(x,y,x+width-1,y+high-1); for(i=0;i<high;i++)//逐行扫描 { scanPointCount = width;//计算出每一行的点数 while(scanPointCount>0)//如果这一行的点数大于7 { if(scanPointCount>7) { LCD_ScanLine_Byte(x,y,charPtr,8,overlap); scanPointCount -= 8; charPtr++; x += 8; } else { LCD_ScanLine_Byte(x,y,charPtr,scanPointCount,overlap); charPtr++; break; } } x = x0; y++; } } /***************************************************************************** * @name :void LCD_ShowChinese(u16 x, u16 y, u8 *s, u8 charSize,u8 mode) * @date :2018-08-09 * @function :Display a single Chinese character * @parameters :x:the bebinning x coordinate of the Chinese character y:the bebinning y coordinate of the Chinese character s:the start address of the Chinese character charSize:size of the Chinese character mode:0-no overlying,1-overlying * @retvalue :None ******************************************************************************/ void LCD_ShowChinese(u16 x, u16 y, u8 *s, u8 charSize,bool overlap) { u8 fontCodeSize,fontCharCount,*fontCodePtr; u16 k;//**All notes can be deleted and modified**// fontCodeSize = My_Font_GetCodeSize_CH(charSize)+2; switch(charSize) { case 12:fontCharCount = ArrayCount(fontGBK12);fontCodePtr = (u8 *)fontGBK12;break; case 16:fontCharCount = ArrayCount(tfont16);fontCodePtr = (u8 *)tfont16;break; case 24:fontCharCount = ArrayCount(tfont24);fontCodePtr = (u8 *)tfont24;break; case 32:fontCharCount = ArrayCount(tfont32);fontCodePtr = (u8 *)tfont32;break; default:break; } for (k=0;k<fontCharCount;k++)//遍历每个字模 { if ((*(fontCodePtr)==*(s))&&(*(fontCodePtr+1)==*(s+1)))//对比字符编码 { fontCodePtr+=2; LCD_DrawMatrixCode(x,y,charSize,charSize,fontCodePtr,overlap); break; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响 } fontCodePtr += fontCodeSize;//指向下一个字模的地址 } LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口为全屏 } /***************************************************************************** * @name :void LCD_ShowChar(u16 x,u16 y,u16 fc, u16 bc, u8 num,u8 size,u8 mode) * @date :2018-08-09 * @function :Display a single English character * @parameters :x:the bebinning x coordinate of the Character display position y:the bebinning y coordinate of the Character display position num:the ascii code of display character(0~94) size:the size of display character mode:0-no overlying,1-overlying * @retvalue :None ******************************************************************************/ void LCD_ShowChar(u16 x,u16 y, u8 charCode,u8 charSize,bool overlap) { u8 *matrixPtr; if(x>(lcddev.width-charSize/2)||y>(lcddev.height-charSize)) return; charCode=charCode-' ';//得到偏移后的值 LCD_SetWindows(x,y,x+charSize/2-1,y+charSize-1);//设置单个文字显示窗口 switch(charSize) { case 12:matrixPtr=(u8 *)asc2_1206;break; case 16:matrixPtr=(u8 *)asc2_1608;break; #ifdef ACS_2412 case 24:matrixPtr=(u8 *)asc2_2412;break; #endif #ifdef ACS_3216 case 32:matrixPtr=(u8 *)asc2_3216;break; #endif default:break; } //**All notes can be deleted and modified**// LCD_DrawMatrixCode(x,y,charSize/2,charSize,matrixPtr,overlap); LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口为全屏 } /***************************************************************************** * @name :void Show_Str(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode) 显示一个字符串 可以为中文 显示的中文取模必须在放到lcd_font.h中 * @function :Display Chinese and English strings * @parameters :x:the bebinning x coordinate of the Chinese and English strings y:the bebinning y coordinate of the Chinese and English strings str:the start address of the Chinese and English strings size:the size of Chinese and English strings mode:0-no overlying,1-overlying * @retvalue :None ******************************************************************************/ void LCD_ShowString(u16 x, u16 y, char *str,u8 charSize,bool overlap) { u16 x0=x; if(charSize>32)// { charSize = 32; } while(*str!=0)//数据未结束 { if((u8)(*str)<0x80) { if(*str=='\r')//回车符号 { y+=charSize; x=x0; if(*(str+1)=='\n')//换行符号 { str++; } } else { LCD_ShowChar(x,y,*str,charSize,overlap); x+=charSize/2; //字符,为全字的一半 } str++; } else//中文 { LCD_ShowChinese(x,y,(u8 *)str,charSize,overlap); str+=2; x+=charSize;//下一个汉字偏移 } } } /***************************************************************************** * @name :void Gui_StrCenter(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode) * @date :2018-08-09 * @function :Centered display of English and Chinese strings * @parameters :x:the bebinning x coordinate of the Chinese and English strings y:the bebinning y coordinate of the Chinese and English strings str:the start address of the Chinese and English strings size:the size of Chinese and English strings mode:0-no overlying,1-overlying * @retvalue :None ******************************************************************************/ void LCD_StrCenter(u16 x, u16 y, char *str,u8 charSize,bool overlap) { u16 len=strlen((const char *)str); u16 x1=(lcddev.width-len*8)/2; LCD_ShowString(x1,y,str,charSize,overlap); } u16 LCD_GetPos_X(u8 charSize,u8 index)// { if(index<=lcddev.width/(charSize>>1)) { return index*(charSize>>1); } return 0; } u16 LCD_GetPos_Y(u8 charSize,u8 index)// { if(index<=lcddev.height/(charSize)) { return index*(charSize); } return 0; }
05-11
#include <reg52.h> #define uchar unsigned char #define uint unsigned int //数码管段选定义 0 1 2 3 4 5 6 7 8 9 uchar code smg_du[]={0x28,0xee,0x32,0xa2,0xe4,0xa1,0x21,0xea,0x20,0xa0}; //断码 //数码管位选定义 uchar code smg_we[]={0xef,0xdf,0xbf,0x7f}; uchar dis_smg[4] = {0}; uchar smg_i = 3; //显示数码管的个位数 sbit SCL=P2^2; //SCL定义为P2口的第2位脚,连接ADC0832SCL脚 sbit DO=P2^3; //DO定义为 P2口的第3位脚,连接ADC0832DO脚 sbit CS=P2^0; //CS定义为 P2口的第0位脚,连接ADC0832CS脚 /***********************1ms延时函数*****************************/ void delay_1ms(uint q) { uint i,j; for(i=0;i<q;i++) for(j=0;j<120;j++); } /***********读数模转换数据********************************************************/ //请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832的串行协议进行的 unsigned char ad0832read(bit SGL,bit ODD) { unsigned char i=0,value=0; SCL=0; DO=1; CS=0; //开始 SCL=1; //第一个上升沿 SCL=0; DO=ODD; SCL=1; //第二个上升沿 SCL=0; DO=SGL; for(i=0;i<8;i++) { SCL=0; //开始从第四个下降沿接收数据 value<<=1; SCL=1; if(DO) value++; } return value; } /***********************数码显示函数*****************************/ void display() { uchar i; for(i=0;i<smg_i;i++) { P1 = 0xff; //消隐 P3 = smg_we[i]; //位选 P1 = dis_smg[i]; //段选 delay_1ms(1); } } /*****************主函数********************/ void main() { uint temp; while(1) { display(); //数码管显示函数 temp = ad0832read(1,0); //采集电压 temp = temp * 100 / 255 * 5 * 2; dis_smg[2]=smg_du[temp/100%10] & 0xdf; //得到百位 dis_smg[1]=smg_du[temp/10%10]; //十位 dis_smg[0]=smg_du[temp%10]; //个位 } }
06-14
#include <driverlib.h> #include <stdio.h> #include <stdint.h> #include <stdbool.h> #include "LCD_TFT_ILI9341.h" #include "Font_lib.h" #include "LCD_Display.h" #include "Segment_LED_Display.h" #include "SDCard.h" #include "TCA8418.h" #include "stdarg.h" #include "Hal_IIC.h" #include "Hal_Wheel.h" #include "HAL_wireUart.h" // 心率监测相关定义 #define NORMAL_LOW_THRESHOLD 60 // 正常心率下限 #define NORMAL_HIGH_THRESHOLD 100 // 正常心率上限 #define ADC_SAMPLE_INTERVAL 500 // ADC采样间隔(ms) // LED引脚定义 #define LED1 GPIO_PIN3 #define LED2 GPIO_PIN4 #define LED3 GPIO_PIN1 #define LED4 GPIO_PIN2 #define LED5 GPIO_PIN7 // ADC配置 - 使用数值代替未定义的宏 #define ADC_INPUT_PIN GPIO_PIN0 #define ADC_INPUT_PORT GPIO_PORT_P6 #define ADC_INPUT_CHANNEL 0 // A0通道 // ADC14配置常量 - 使用数值代替标识符 #define ADC_CLOCKSOURCE_SMCLK 0x00000000 #define ADC_PREDIVIDER_1 0x00000000 #define ADC_DIVIDER_1 0x00000000 #define ADC_RESOLUTION_14BIT 0x00000003 #define ADC_MEM0 0 #define ADC_VREFPOS_AVCC 0x00000000 #define ADC_VREFNEG_VSS 0x00000000 #define ADC_PULSE_WIDTH_192 0x00000003 // GPIO配置常量 #define GPIO_ANALOG_MODE 0x00000000 // 模拟模式 // ADC采样模式常量 #define ADC_MANUAL_MODE 0x00000000 // 手动采样模式 //***************************************************************************** // //XT1 Crystal Frequency being used // //***************************************************************************** #define UCS_XT1_CRYSTAL_FREQUENCY 32768 //***************************************************************************** // //Target frequency for MCLK in kHz // //***************************************************************************** #define UCS_MCLK_DESIRED_FREQUENCY_IN_KHZ 20000 //***************************************************************************** // //MCLK/FLLRef Ratio // //***************************************************************************** #define UCS_MCLK_FLLREF_RATIO 625 //***************************************************************************** // //Variable to store returned STATUS_SUCCESS or STATUS_FAIL // //***************************************************************************** uint8_t returnValue = 0; //***************************************************************************** // //Variable to store status of Oscillator fault flags // //***************************************************************************** uint16_t status; // 全局变量 uint16_t heart_rate = 0; // 存储心率值 bool heart_rate_display = false; // 心率显示标志 bool alert_flag = false; // 报警标志 uint32_t last_adc_time = 0; // 上次ADC采样时间 uint32_t blink_timer = 0; // LED闪烁计时器 bool led_blink_state = false; // LED闪烁状态 void short_delay(void) { //Delay 0.5s __delay_cycles(1000000); } // ADC初始化函数 - 使用数值常量 void ADC_init(void) { // 配置ADC输入引脚(P6.0)为模拟模式 GPIO_setAsPeripheralModuleFunctionInputPin( ADC_INPUT_PORT, ADC_INPUT_PIN, GPIO_ANALOG_MODE // 使用模拟模式 ); // 初始化ADC14模块 ADC14_enableModule(); ADC14_initModule(ADC_CLOCKSOURCE_SMCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1, ADC_RESOLUTION_14BIT); // 配置ADC存储寄存器 ADC14_configureSingleSampleMode(ADC_MEM0, true); ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_AVCC | ADC_VREFNEG_VSS, ADC_INPUT_CHANNEL, false); // 设置采样周期 ADC14_setSampleHoldTime(ADC_PULSE_WIDTH_192, ADC_PULSE_WIDTH_192); // 使能ADC ADC14_enableSampleTimer(ADC_MANUAL_MODE); // 使用手动模式 ADC14_enableConversion(); } // 读取心率ADC值 uint16_t read_heart_rate_adc(void) { ADC14_startConversion(); while(ADC14_isBusy()); return ADC14_getResult(ADC_MEM0); } // 将ADC值转换为心率值 (0-16383 -> 30-200 BPM) uint16_t convert_to_heart_rate(uint16_t adc_value) { // 简单线性转换: ADC值映射到30-200 BPM范围 return (adc_value * 170) / 16383 + 30; } // LED闪烁处理函数 void handle_led_blink(void) { static uint32_t last_blink_time = 0; uint32_t current_time = blink_timer; if (current_time - last_blink_time >= 500) { // 500ms闪烁周期 last_blink_time = current_time; led_blink_state = !led_blink_state; if (led_blink_state) { Board_ledOn(LED1 | LED2 | LED3 | LED4 | LED5); } else { Board_ledOff(LED1 | LED2 | LED3 | LED4 | LED5); } } } // 显示心率值 void display_heart_rate(uint16_t rate) { char hr_str[20]; sprintf(hr_str, "Heart Rate: %d", rate); LCD_StringDisplay(20, 50, hr_str); // 显示心率状态 if (rate < NORMAL_LOW_THRESHOLD) { LCD_StringDisplay(20, 80, "Status: LOW"); } else if (rate > NORMAL_HIGH_THRESHOLD) { LCD_StringDisplay(20, 80, "Status: HIGH"); } else { LCD_StringDisplay(20, 80, "Status: NORMAL"); } } #define uchar unsigned char uchar buttonS3_flag; uchar buttonS4_flag; // 瑩攫 #define ROWS 3 #define COLS 4 char keymap[COLS][ROWS] = {{'*', '0', '#'}, {'7', '8', '9'}, {'4', '5', '6'}, {'1', '2', '3'},}; /* Declaring Global Variables */ uint8_t buffer[20]; int k; bool pressed; uint8_t row,col; //LED腑場宎趙 void Board_Led_init(void) { //P9.x output GPIO_setOutputLowOnPin( GPIO_PORT_P9, GPIO_PIN3 | GPIO_PIN4 | GPIO_PIN1 | GPIO_PIN2); GPIO_setAsOutputPin( GPIO_PORT_P9, GPIO_PIN3 | GPIO_PIN4 | GPIO_PIN1 | GPIO_PIN2); //P8.x output GPIO_setOutputLowOnPin( GPIO_PORT_P8, GPIO_PIN7); GPIO_setAsOutputPin( GPIO_PORT_P8, GPIO_PIN7); } void buttoninit(void) { // Button S3 GPIO_setAsInputPin( GPIO_PORT_P2, GPIO_PIN6 ); GPIO_selectInterruptEdge( GPIO_PORT_P2, GPIO_PIN6, GPIO_HIGH_TO_LOW_TRANSITION ); GPIO_enableInterrupt( GPIO_PORT_P2, GPIO_PIN6 ); GPIO_clearInterrupt( GPIO_PORT_P2, GPIO_PIN6 ); // Button S4 GPIO_setAsInputPin( GPIO_PORT_P3, GPIO_PIN1 ); GPIO_selectInterruptEdge( GPIO_PORT_P3, GPIO_PIN1, GPIO_HIGH_TO_LOW_TRANSITION ); GPIO_enableInterrupt( GPIO_PORT_P3, GPIO_PIN1 ); GPIO_clearInterrupt( GPIO_PORT_P3, GPIO_PIN1 ); } void Board_ledOn(unsigned char ledMask) { if (ledMask & LED1) GPIO_setOutputHighOnPin(GPIO_PORT_P9, GPIO_PIN3); if (ledMask & LED2) GPIO_setOutputHighOnPin(GPIO_PORT_P9, GPIO_PIN4); if (ledMask & LED3) GPIO_setOutputHighOnPin(GPIO_PORT_P9, GPIO_PIN1); if (ledMask & LED4) GPIO_setOutputHighOnPin(GPIO_PORT_P9, GPIO_PIN2); if (ledMask & LED5) GPIO_setOutputHighOnPin(GPIO_PORT_P8, GPIO_PIN7); } void Board_ledOff(unsigned char ledMask) { if (ledMask & LED1) GPIO_setOutputLowOnPin(GPIO_PORT_P9, GPIO_PIN3); if (ledMask & LED2) GPIO_setOutputLowOnPin(GPIO_PORT_P9, GPIO_PIN4); if (ledMask & LED3) GPIO_setOutputLowOnPin(GPIO_PORT_P9, GPIO_PIN1); if (ledMask & LED4) GPIO_setOutputLowOnPin(GPIO_PORT_P9, GPIO_PIN2); if (ledMask & LED5) GPIO_setOutputLowOnPin(GPIO_PORT_P8, GPIO_PIN7); } void wait_ms(long i) { while(i) { __delay_cycles(20000); i--; blink_timer++; // 更新闪烁计时器 } } void sysclockInit(void) { //Set VCore = 3 for 20MHz clock PMM_setVCore(PMM_CORE_LEVEL_3); //Set DCO FLL reference = REFO UCS_initClockSignal( UCS_FLLREF, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1 ); //Set ACLK = REFO UCS_initClockSignal( UCS_ACLK, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1 ); //Set Ratio and Desired MCLK Frequency and initialize DCO UCS_initFLLSettle( UCS_MCLK_DESIRED_FREQUENCY_IN_KHZ, UCS_MCLK_FLLREF_RATIO ); // Enable global oscillator fault flag SFR_clearInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT); SFR_enableInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT); // Enable global interrupt __bis_SR_register(GIE); } /* * main.c */ void main(void) { //Stop WDT WDT_A_hold(WDT_A_BASE); sysclockInit(); Board_Led_init(); lcd_init(); LCD_ILI9341_TFT_background(White); LCD_ILI9341_TFT_foreground(Black); // 显示开机界面 LCD_ILI9341_TFT_cls(White); LCD_StringDisplay(60, 100, "Heart Rate Monitor"); LCD_StringDisplay(70, 130, "System Ready"); // LED数码管全亮 Board_ledOn(LED1 | LED2 | LED3 | LED4 | LED5); Segment_LED_init(); Segment_LED_SHOW(); short_delay(); Segment_LED_Close(); Board_ledOff(LED1 | LED2 | LED3 | LED4 | LED5); // 初始化ADC ADC_init(); // 初始化键盘 I2c_Init(USCI_B1_BASE, GPIO_PORT_P8,GPIO_PIN5, GPIO_PORT_P8,GPIO_PIN6); GPIO_setAsOutputPin(GPIO_PORT_P9,GPIO_PIN5); TCA8418_init(); TCA8418_matrix(ROWS, COLS); TCA8418_flush(); // 初始化按钮 buttonS3_flag = 0; buttonS4_flag = 0; buttoninit(); __bis_SR_register(GIE); while(1) { if (TCA8418_available() > 0) { // 获取键盘事件 k = TCA8418_getEvent(); pressed = k & 0x80; k &= 0x7F; k--; row = k / 10; col = k % 10; } if (pressed) { pressed = false; // 重置按键状态 // 按键1:启动心率监测 if (row == 3 && col == 0) // '1'键 { LCD_ILI9341_TFT_cls(White); LCD_StringDisplay(20, 20, "Heart Rate Monitoring"); heart_rate_display = true; alert_flag = false; Board_ledOff(LED1 | LED2 | LED3 | LED4 | LED5); } // 按键2:清除显示/解除报警 else if (row == 3 && col == 1) // '2'键 { LCD_ILI9341_TFT_cls(White); heart_rate_display = false; alert_flag = false; Board_ledOff(LED1 | LED2 | LED3 | LED4 | LED5); } } // 心率监测模式 if (heart_rate_display) { // 定期采样心率 uint32_t current_time = blink_timer; if (current_time - last_adc_time >= ADC_SAMPLE_INTERVAL) { last_adc_time = current_time; uint16_t adc_value = read_heart_rate_adc(); heart_rate = convert_to_heart_rate(adc_value); display_heart_rate(heart_rate); // 检查心率是否异常 if (heart_rate < NORMAL_LOW_THRESHOLD || heart_rate > NORMAL_HIGH_THRESHOLD) { alert_flag = true; LCD_StringDisplay(20, 110, "ALERT! Abnormal Heart Rate"); } else { alert_flag = false; } } } // 异常报警处理 if (alert_flag) { handle_led_blink(); } // 系统复位按钮(S3) if (buttonS3_flag == 1) { heart_rate_display = false; alert_flag = false; LCD_ILI9341_TFT_background(White); LCD_ILI9341_TFT_foreground(Black); LCD_ILI9341_TFT_cls(White); LCD_StringDisplay(60, 100, "Heart Rate Monitor"); LCD_StringDisplay(70, 130, "System Ready"); Board_ledOff(LED1 | LED2 | LED3 | LED4 | LED5); buttonS3_flag = 0; } // 主循环延时 wait_ms(10); } } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=UNMI_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(UNMI_VECTOR))) #endif void NMI_ISR(void) { do { // If it still can't clear the oscillator fault flags after the timeout, // trap and wait here. status = UCS_clearAllOscFlagsWithTimeout(1000); } while(status != 0); } #pragma vector=PORT2_VECTOR __interrupt void PORT2ISR(void) { volatile unsigned int i; for(i = 0; i < 15000; i++); if(!(P2IN & 0x40)) { switch(__even_in_range(P2IV, 16)) { case 0: break; // Vector 0: No interrupt case 2: break; // Vector 2: P2.0 interrupt highest priority case 4: break; // Vector 4: P2.1 interrupt case 6: break; // Vector 6: P2.2 interrupt case 8: break; // Vector 8: P2.3 interrupt case 10: break; // Vector 10: P2.4 interrupt case 12: break; // Vector 12: P2.5 interrupt case 14: buttonS3_flag = 1; buttonS4_flag = 0;// set key pressed flag GPIO_clearInterrupt(GPIO_PORT_P2, GPIO_PIN6); // clear interrupt flag break; // Vector 14: P2.6 interrupt case 16: break; // Vector 16: P2.7 interrupt lowest priority default: break; } } } 报错提示:#141 too many arguments in function call
最新发布
06-17
#include <reg52.h> #include <intrins.h> //???? sbit SCL = P1^0; // ???? sbit SI = P1^1; // ???? sbit A0 = P1^2; // ??/???? sbit CS1 = P1^3; // ??1 sbit RES = P1^4; // ?? //?????? #define LCD_WIDTH 128 #define LCD_HEIGHT 64 #define LCD_PAGES (LCD_HEIGHT/8) //???? void delay_us(unsigned int t) { while(t--); } void delay_ms(unsigned int t) { unsigned int i, j; for(i=0; i<t; i++) for(j=0; j<120; j++); } //?????? void write_byte(unsigned char dat) { unsigned char i; for(i=0; i<8; i++) { SCL = 0; SI = (dat & 0x80) ? 1 : 0; // ???? dat <<= 1; SCL = 1; _nop_(); } SCL = 0; } //???? void send_cmd(unsigned char cmd) { CS1 = 0; // ???? A0 = 0; // ???? write_byte(cmd); CS1 = 1; // ???? } //???? void send_data(unsigned char dat) { CS1 = 0; // ???? A0 = 1; // ???? write_byte(dat); CS1 = 1; // ???? } //LCD??? void lcd_init() { RES = 0; // ???? delay_ms(10); RES = 1; delay_ms(10); send_cmd(0xE2); // ???? delay_ms(10); send_cmd(0xA2); // ?????(1/9 bias) send_cmd(0xA1); // SEG???? send_cmd(0xC0); // COM???? send_cmd(0x24); // ????? send_cmd(0x81); // ?????? send_cmd(0x20); // ??? send_cmd(0x2F); // ????(??????) send_cmd(0x40); // ???????0 send_cmd(0xAF); // ???? } //?????? void set_pos(unsigned char page, unsigned char column) { send_cmd(0xB0 | (page & 0x0F)); // ??? send_cmd(0x10 | ((column >> 4) & 0x0F)); // ????4? send_cmd(0x00 | (column & 0x0F)); // ????4? } //?? void clear_screen() { unsigned char i, j; for(i=0; i<LCD_PAGES; i++) { set_pos(i, 0); for(j=0; j<LCD_WIDTH; j++) { send_data(0x00); } } } // ??????(??????????) void display_partial_image(unsigned char page, unsigned char col, const unsigned char *img_data, unsigned char width, unsigned char height_pages) { unsigned char p, c; for(p=0; p<height_pages; p++) { set_pos(page + p, col); for(c=0; c<width; c++) { send_data(img_data[p*width + c]); } } } code unsigned char smile_32x32_negative[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x80, 0xC0,0xE0,0xE0,0xE0,0xA0,0xA0,0xE0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF8,0xF8,0xF8, 0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFE,0xFE,0xFE,0xFE,0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0xF8,0xF8,0xF0,0xF0,0xF0,0xF8,0xF8,0xF8,0xF8,0xF0,0xF0,0xF0, 0xF0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xA0,0x20,0x60,0x40,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xF0,0xF8,0xF9,0xFD,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBE,0x24,0x60,0x40, 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x40,0x03,0x0F,0x3F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0x7F,0x3F,0x07,0x01,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x03,0x03,0x07,0x07,0x07,0x07,0x07,0x07, 0x07,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x07,0x07,0x07,0x07,0x07,0x07, 0x07,0x07,0x07,0x07,0x07,0x07,0x0F,0x0F,0x0F,0x1F,0x3F,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x7F,0x7F,0x3F,0x1F,0x0E,0x00,0x01, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x08,0x00,0x03,0x0F,0x1F, 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x0C,0x0C,0x2C,0x2C,0x3C,0x3C,0x1C, 0x38,0x38,0x38,0x38,0x38,0x38,0x18,0x18,0x58,0x18,0x18,0x10,0x10,0x00,0x00,0x00, 0x00,0x00,0x00,0xC0,0xE0,0xE0,0x60,0xD0,0xD8,0x78,0x78,0x38,0x78,0x78,0x78,0x78, 0x78,0x38,0xB8,0xF8,0x78,0x78,0x18,0x18,0x18,0x1C,0x1C,0x18,0x08,0x00,0x61,0x7F, 0x7F,0x7F,0x7F,0x7F,0x3F,0x1F,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE0, 0xE0,0xE0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x40,0x40,0x4C,0x7F,0x7F,0x7F,0x79,0x70,0x70,0x70,0x30,0x20,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x20,0x30,0x10,0x98,0xC8,0xE0,0xE8,0xE0,0xE0,0xC0,0xC0,0xC0, 0xC0,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x78,0xF8,0xFC,0xFC,0xFC,0xFC,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0x7F,0x7F,0x3F,0x3F,0x1E,0x1C,0x00,0x00,0x08,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x10,0x10,0x10,0x18,0xD8,0xD8,0xD8,0xDC,0xEC, 0xEC,0xEC,0xCC,0xCE,0xCE,0xC6,0xC6,0xC6,0xE6,0xF6,0xE7,0xE7,0xE5,0xE5,0xE4,0xE4, 0xE4,0xEC,0xEC,0xEE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFE,0xFE,0xFE,0xFC,0xFC,0xFC,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFC,0xFC, 0x68,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x7F,0x3F,0x3F,0x1F,0x1F,0x0F,0x0F,0x07,0x07,0x03, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xC0,0xE8,0xE9, 0x68,0x6C,0x6C,0x2C,0x24,0xAC,0xFC,0xFC,0xEC,0xFE,0xFE,0xFD,0xFD,0xFD,0xFD,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCB,0xDF,0xDF,0x3F,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x9F,0x1F, 0x00,0x00,0x01,0x01,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x07,0x0F,0x2D, 0x24,0x43,0x4B,0x5E,0x5E,0x18,0x38,0x38,0x30,0x30,0x60,0x60,0x60,0xC0,0xC0,0xC0, 0x80,0x80,0x80,0xC0,0xC0,0xC0,0x60,0x60,0x20,0x30,0x70,0x90,0x90,0x10,0x10,0x10, 0x10,0x98,0x98,0x88,0x88,0x8C,0x8C,0x84,0xC6,0xC2,0xC2,0xE3,0xE1,0xE1,0xF0,0xF8, 0xF8,0xFC,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFD,0xFE,0xFF, 0x7E,0x79,0x3F,0x1F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x7F,0x3F,0x3F,0x3F,0x1F,0x0};/*"?????",0*/ // ?????(????) code unsigned char FONT_TABLE[37][5] = { // ???? A-Z {0x7C,0x12,0x11,0x12,0x7C}, // A {0x7F,0x49,0x49,0x49,0x36}, // B {0x3E,0x41,0x41,0x41,0x22}, // C {0x7F,0x41,0x41,0x22,0x1C}, // D {0x7F,0x49,0x49,0x49,0x41}, // E {0x7F,0x09,0x09,0x09,0x01}, // F {0x3E,0x41,0x49,0x49,0x7A}, // G {0x7F,0x08,0x08,0x08,0x7F}, // H {0x00,0x41,0x7F,0x41,0x00}, // I {0x20,0x40,0x41,0x3F,0x01}, // J {0x7F,0x08,0x14,0x22,0x41}, // K {0x7F,0x40,0x40,0x40,0x40}, // L {0x7F,0x02,0x0C,0x02,0x7F}, // M {0x7F,0x04,0x08,0x10,0x7F}, // N {0x3E,0x41,0x41,0x41,0x3E}, // O {0x7F,0x09,0x09,0x09,0x06}, // P {0x3E,0x41,0x51,0x21,0x5E}, // Q {0x7F,0x09,0x19,0x29,0x46}, // R {0x26,0x49,0x49,0x49,0x32}, // S {0x01,0x01,0x7F,0x01,0x01}, // T {0x3F,0x40,0x40,0x40,0x3F}, // U {0x1F,0x20,0x40,0x20,0x1F}, // V {0x3F,0x40,0x38,0x40,0x3F}, // W {0x63,0x14,0x08,0x14,0x63}, // X {0x07,0x08,0x70,0x08,0x07}, // Y {0x61,0x51,0x49,0x45,0x43}, // Z // ?? 0-9 {0x3E,0x45,0x49,0x51,0x3E}, // 0 {0x00,0x21,0x7F,0x01,0x00}, // 1 {0x21,0x43,0x45,0x49,0x31}, // 2 {0x42,0x41,0x51,0x69,0x46}, // 3 {0x0C,0x14,0x24,0x7F,0x04}, // 4 {0x72,0x51,0x51,0x51,0x4E}, // 5 {0x1E,0x29,0x49,0x49,0x06}, // 6 {0x40,0x47,0x48,0x50,0x60}, // 7 {0x36,0x49,0x49,0x49,0x36}, // 8 {0x30,0x49,0x49,0x4A,0x3C}, // 9 // ????(??) {0x00,0x00,0x00,0x00,0x00} // ??(??36) }; // ?????(???0-7,???0-131) void display_string(unsigned char page, unsigned char start_col, char *str) { unsigned char c_idx,i; while(*str != '\0') { char c = *str++; // ????(??????????) if(c >= 'A' && c <= 'Z') c_idx = c - 'A'; else if(c >= 'a' && c <= 'z') c_idx = c - 'a'; // ????? else if(c >= '0' && c <= '9') c_idx = 26 + (c - '0'); else if(c == ' ') c_idx = 36; else continue; // ??????? // ???? if(c_idx >= 37) continue; // ??????????? set_pos(page, start_col); for( i=0; i<5; i++) { send_data(FONT_TABLE[c_idx][i]); } send_data(0x00); // ?????? start_col += 6; // ?????6?(5??+1??) // ????(132???) if(start_col > 126) break; // 132-6=126???????? } } void main() { lcd_init(); clear_screen(); // ???? display_partial_image(0, 0, smile_32x32_negative, 128, 8); // ?3,?60 // ?????? // display_string(1, 10, "Hello BEAT"); while(1); }修改改代码使单片机 STC15W4K32S4 通过控制OK BACK DOWN这三个按键控制显示屏显示三级菜单,最开始lcd上按列显示RUN STOP ,最开始光标在RUN上当我按下DOWN按键时,光标向下移动到STOP,当我在RUN下按下OK按键时,进入RUN子菜单,当本次按下时间不超过两秒,lcd上按列显示“OKshort ”,当本次按下的时间超过2s时,显示“OKlong runing”,当我在STOP下按下OK按键时,进入STOP子菜单,当本次按下时间不超过两秒,lcd上按列显示“STOPshort ”,当本次按下的时间超过2s时,显示“STOPlong stopping 当我按下BACK按键时,返回到最初页面,帮我生成程序代码Protues仿真
05-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值