此程序是用的flash里面装的字库的方法来做的,可以显示各种字和字符,可以各种移
动,左移,右移,上下移动都可以。
以下是该程序的主要代码(所谓的主要代码就是跟移动有关的代码)
/**************************************************************************************************
**程序名称:LedDisplay(void) **输入参数:无 **输出参数:无 **返 回 值:无
**描 述:LED显示板一行显示程序。此程序读取显示缓存中的数据,并在LED上显示出来。 **
注:此程序显示的字模为纵向取模。
**************************************************************************************************/
void LedDisplay(void) {
uint16_t offset_addr; uint16_t lenght;
uint8_t *data;
//如果时钟节拍数定义了,说明要使用ucosII了.
// #ifdef OS_TICKS_PER_SEC
,.
// OS_CPU_SR cpu_sr = 0u; // OS_ENTER_CRITICAL();
// #endif offset_addr = (ScanRow / 8) * LED_SET.Width ;
LedScanTime = 0;
/*关显示(消隐)*/ if(!LED_SET.ENMode) { LedEn_H();
} else { LedEn_L(); }
lenght = LED_SET.Width; /* 输出列数据*/
if(!BackFlag) {
data = Buf0 + offset_addr; //关显示
while(lenght--) { LedOutBit(*data,ScanRow); data ++;
}
}
else { data = Buf1 + offset_addr; while(lenght--) { LedOutBit(*data,ScanRow); data ++;
}
}
LedClk_L();
LedLat_L();
LedDelay(10); LedLat_H();
,.
//锁存数据
LedDelay(10); LedLat_L();
offset_addr = LedScanTime;
/*关显示(消隐)*/ if(!LED_SET.ENMode) { LedEn_H();
} else { LedEn_L(); }
/* 输出行扫描信号*/ ScanRow &= 0x0F; LedRow(ScanRow); ScanRow ++;
if(ScanRow == LED_SET.ScanMode) {
ScanRow = 0;
,.
//关显示
//行+1
//16
,.
}
if(ScanRow == LED_SET.FirstRow)
//如果完成一帧扫描,置标志,扫描
完16行
{
ScanFlag = 1;
//只有当ScanFlag = 1时,才能切
换显示内容
} else { }
//如果时钟节拍数定义了,说明要使用ucosII了.
ScanFlag = 0;
// #ifdef OS_TICKS_PER_SEC
// OS_EXIT_CRITICAL();
// #endif
LedDelay(LED_SET.BlankTime);
if(LED_SET.OnOff == ON)
//消隐时间
//如果显示屏配置为显示,则开
显示
{
,.
}
}
if(!LED_SET.ENMode) { } else { }
LedEn_H(); LedEn_L();
//开显示
void Get_HzMat(unsigned char *code,unsigned char *mat,uint8_t size) {
#if OS_CRITICAL_METHOD == 3 //中断函数被设定为模式3 OS_CPU_SR cpu_sr = 0u; #endif
qh = *code; ql = *(++code); unsigned char qh,ql; unsigned char i; unsigned long foffset;
,.
if(qh<0x81||ql<0x40||ql==0xff||qh==0xff) //非常用汉字 ,没有包含
在字库内
{ }
if(ql<0x7f) { }
ql-=0x40;
//注意!
for(i=0;i<(size*2);i++) { }
//结束访问
*mat++ = 0x00;
//填充满格
return;
else { }
ql-=0x41;
qh -= 0x81;
foffset = ((unsigned long)190 * qh + ql) * (size * 2);//得到字库中的字节偏移量
,.
#ifdef OS_TICKS_PER_SEC
//如果时钟节拍数定义了,说明要使用ucosII了.
OS_ENTER_CRITICAL();
#endif
FlashBusy ^= 1;
SPI_FLASH_BufferRead(mat,GBK16_ADDR + foffset,32); FlashBusy ^= 1;
//如果时钟节拍数定义了,说明要使用ucosII了.
//从flash中读取
#ifdef OS_TICKS_PER_SEC
OS_EXIT_CRITICAL();
#endif }
/**************************************************************************************************
**程序名称:Show_Char(int16_t row,int16_t col,uint8_t str,uint8_t back) **输入参数:int16_t row ** ** **
int16_t col uint8_t str
显示行坐标
显示列坐标 指定字符
指示写入字模的显示缓存
uint8_t back
**输出参数:无 **返 回 值:无
**描 述:在指定位置显示一个16*8字符。注:使用font16x8字库。
**************************************************************************************
,.
************/
void Show_Char(int16_t row,int16_t col,uint8_t str,uint8_t back) {
uint8_t *pBuf,*tmp; uint8_t tmpData,tmptt; uint8_t i,j;
tmprow = row % 8; uint8_t tmprow;
// tmpcol = col % 8;
if(!back)//区分两个不同的缓存 { } else { }
tmp = Buf1; tmp =Buf0;
tmptt = str - 32;
,.
for(j = 0;j < 2;j++) {
for(i = 0;i < 8;i++) {
/*判断溢出条件,在这里行可以到-15去*/
if(((row + j) < LED_SET.Height)&&((col + i) >= 0) &&((col + i) <
LED_SET.Width))
{
pBuf = tmp + j*LED_SET.Width + (col + i);//pBuf 的计算方法,纵向
取模
if((row >= 0) && (row < 8))
{
if(j == 0)//判断在上面还是在下面的区域 {
tmpData = *pBuf;
tmpData = ~font16x8[tmptt *16 + 8 * j + i] >>
tmprow;
pBuf += LED_SET.Width; tmpData = *pBuf; tmpData &= 0x00;
*pBuf = tmpData;
,.
tmpData |= (~font16x8[tmptt *16 + 8 * j + i]) << (8 -
tmprow);
tmprow;
*pBuf = tmpData;
} else { tmpData = *pBuf;
tmpData &= 0xff << (8 - tmprow); tmpData |= 0xff >> tmprow;
tmpData &= (~font16x8[tmptt *16 + 8 * j + i]) >> *pBuf = tmpData; }
}
else if((row >=8) && (row < 16)) { if(j == 0) { tmpData = *pBuf; tmpData |= 0xff;
*pBuf = tmpData; ,.
pBuf += LED_SET.Width; tmpData = *pBuf; tmpData &= 0x00;
tmprow;
-tmprow;
tmpData |= (~font16x8[tmptt *16 + 8 * j + i]) >>
*pBuf = tmpData;
}
}
else if((row > -8) && (row <= 0)) { if(j == 1) { tmpData = *pBuf; tmpData &= 0x00;
tmpData |= (~font16x8[tmptt *16 + 8 * j + i]) << tmpData |= 0xff >> (8 + tmprow); *pBuf = tmpData;
pBuf -= LED_SET.Width; tmpData = *pBuf;
tmpData &= 0x00;
,.
tmpData |= ((~font16x8[tmptt *16 + 8 * j + i]) >>(8 +
tmprow)) | (0xff << -tmprow);
tmpData &= ((~font16x8[tmptt *16 + i]) << -tmprow)
|(0xff >> (8 + tmprow));
<<-tmprow;
*pBuf = tmpData;
}
}
else if((row >-16) && (row <= -8)) { if(j == 1) { tmpData = *pBuf; tmpData |= 0xff;
*pBuf = tmpData; pBuf -= LED_SET.Width; tmpData = *pBuf; tmpData &= 0x00;
tmpData |= (~font16x8[tmptt *16 + 8 * j + i])
tmpData |= 0xff >> (8 + tmprow);
*pBuf = tmpData;
,.
}
}
}
}
}
}
/**************************************************************************************************
**程序名称:void Show_HZ(int16_t row,int16_t col,uint8_t *hzk,uint8_t back) **输入参数:int16_t row ** ** **
int16_t col uint8_t *hzk
显示行坐标
显示列坐标
指向指定汉字内码的指针 指示写入字模的显示缓存
uint8_t back
**输出参数:无 **返 回 值:无
**描 述:在指定位置显示一个16*16汉字。注:使用GBK16字库。
**************************************************************************************************/
void Show_HZ(int16_t row,int16_t col,uint8_t *hzk,uint8_t back) {
uint8_t dzk[32];
uint8_t *pBuf,*tmp; uint8_t tmprow;
uint8_t tmpData; uint8_t i,j;
/* 纵向取模字库 */ Get_HzMat(hzk,dzk,16);
tmprow = row % 8; if(!back) { pBuf = Buf0;
} else { pBuf = Buf1; }
tmp = pBuf;
,.
// 取字模
,.
for(j = 0;j < 2;j++) {
for(i = 0;i < 16;i++) {
/*判断溢出条件,在这里行可以到-15去*/
if(((row + j) < LED_SET.Height)&&((col + i) >= 0) &&((col + i) <
LED_SET.Width))
{
pBuf = tmp + j*LED_SET.Width + (col + i);//pBuf 的计算方法,纵向
取模
if((row >= 0) && (row < 8))
{
if(j == 0)//判断在上面还是在下面的区域 {
tmpData = *pBuf; tmpData &=0x00;
//全部清零
tmpData |= (~dzk[2 * i + (j % 2)]) >> tmprow; //将高
位清零,低位放的是原来高位的
pBuf += LED_SET.Width;
*pBuf = tmpData;
,.
tmpData = *pBuf; tmpData &=0x00; //清零
tmpData |= (~dzk[2 * i + (j % 2)]) << (8 - tmprow);//
将前一个低位的位放到高位,低位为0
tmpData &=0xff << (8-tmprow); tmpData |= 0xff >> tmprow;
//全部清零 //高位不变,低位
全为1
tmpData &= ~(dzk[2 * i + (j % 2) + 1] >> tmprow);
//将高位清零,低位放的是原来高位的
} else {
tmpData = *pBuf;
tmpData &=0xff << (8-tmprow); tmpData |= 0xff >> tmprow;
//全部清零 //高位不变,低位
*pBuf = tmpData;
// // // // // 全为1 // //
tmpData &= ~(dzk[2 * i + (j % 2)] >> tmprow); //
将高位清零,低位放的是原来高位的 // //
}
*pBuf = tmpData;
,.
}
else if((row >=8) && (row < 16)) {
if(j == 0) {
tmpData = *pBuf; tmpData |= 0xff; *pBuf = tmpData;
}
}
pBuf += LED_SET.Width; tmpData = *pBuf; tmpData &= 0x00;
tmpData |= (~dzk[2 * i + (j % 2)]) >> tmprow; *pBuf = tmpData;
else if((row > -8) && (row <= 0)) {
if(j == 1) {
tmpData = *pBuf; tmpData &= 0x00;
,.
tmpData |= ~dzk[2 * i + (j % 2)] << -tmprow; tmpData |= 0xff >> (8 + tmprow); *pBuf = tmpData;
pBuf -= LED_SET.Width; tmpData = *pBuf; tmpData &= 0x00;
tmpData |= (~dzk[2 * i + (j % 2)] >>(8 + tmprow)) |
(0xff << -tmprow);
tmpData &= (~dzk[2 * i + (j % 2) - 1] << -tmprow)
|(0xff >> (8 + tmprow));
}
else if((row >-16) && (row <= -8)) {
if(j == 1) {
tmpData = *pBuf; tmpData |= 0xff; *pBuf = tmpData; }
*pBuf = tmpData;
,.
}
}
}
}
}
}
pBuf -= LED_SET.Width; tmpData = *pBuf; tmpData &= 0x00;
tmpData |= (~dzk[2 * i + (j % 2)]) <<-tmprow; tmpData |= 0xff >> (8 + tmprow); *pBuf = tmpData;
/**************************************************************************************************
**程序名称:Show_Str(int16_t x,int16_t y,uint8_t *str,uint8_t back) **输入参数:int16_t y ** **
int16_t x uint8_t *str
显示行坐标 显示列坐标 指向字符串的指针
**输出参数:无 **返 回 值:无
**描 述:在指定位置开始显示一个字符串。(x,y):起始坐标。
,.
**************************************************************************************************/
void Show_Str(int16_t x,int16_t y,uint8_t *str) {
int16_t x0 = x; int16_t y0 = y; uint8_t bHz = 0; uint8_t forget_back;
/* 检测显示缓存位置,不允许写入正在显示的缓存*/ if(BackFlag) { } else { }
LedClear(forget_back);
//数据未结束
//清空要写入的缓存
forget_back = 1;
//后台
forget_back = 0;
//前台
//BackFlag 前后台标志,初始值为1
//字符或者中文
while(*str != 0)
{
if(!bHz)
//bHz = 1 表示是中文
{ if(*str > 0x80)bHz=1;
//中文
else //字符
{ if(*str==13)
//换行符号,忽略 {
str++; } else { Show_Char(y0,x0,*str,forget_back); str++;
}
x0 += 8;
//字符,为全字的一半 }
}
else
//中文
{ bHz = 0;
//有汉字库
Show_HZ(y0,x0,str,forget_back);
,.
//有效部分写入
,.
str += 2; x0 += 16;
//下一个汉字偏移
} } }
/* 等待一帧显示完成,将显示缓存切换到当前缓存*/ while(!ScanFlag); BackFlag = forget_back;
void LedClose(void) { }
/*关显示*/ if(!LED_SET.ENMode) { } else { }
LedEn_L();
LedEn_H();
//关显示
LED_SET.OnOff = OFF;
void LedOpen(void) { /*开显示(消隐)*/ if(!LED_SET.ENMode) { LedEn_L();
} else { LedEn_H(); }
LED_SET.OnOff = ON;
}
/*左移显示*/
void DisplayMvoeLeft(void * p_arg) { uint8_t *str;
int16_t i;
uint16_t lenght; ,.
//关显示
(void)p_arg; while(1) { //str = \"写自己要显示的东西!\"; str = p_arg;
lenght = OS_StrLen(str) * 8;
for(i = -LED_SET.Width; i < lenght; i +=2) { Show_Str(0 - i,0,str); //Show_HZ(3,10,str,0); //Show_HZ(3,10,str,1); OSTimeDlyHMSM(0,0,0,500); }
}
}
/*右移显示*/
void DisplayMoveRight(void * p_arg) { uint8_t *str;
,.
//左移,每次移动2位 int16_t i; uint16_t lenght;
(void)p_arg; while(1) { //str = \"写自己要显示的东西!\"; str = p_arg;
lenght = OS_StrLen(str) * 8;
for(i = lenght; i > -(LED_SET.Width); i -=2) { Show_Str(0 - i,0,str);
OSTimeDlyHMSM(0,0,0,500); }
}
}
/*上移动显示*/
void DisplayMoveUp(void * p_arg) {
uint8_t *str;
,.
//左移,每次移动2位 ,.
int16_t i;
// (void)p_arg; }
/*下移显示*/
void DisplayMoveDown(void * p_arg) {
uint8_t *str;
int16_t i; while(1) { }
str = p_arg;
for(i = 15;i > -16;i--) { }
Show_Str(0, i,str);
OSTimeDlyHMSM(0,0,0,500);
// (void)p_arg;
,.
}
while(1) { }
str = p_arg;
for(i = -15;i < 16;i++) { }
Show_Str(0, i,str);
OSTimeDlyHMSM(0,0,0,500);
/*不移动,但是一直在闪着显示*/ void DisplayBlink(void *p_arg) {
while(1) {
lenght = OS_StrLen(str) * 8; uint16_t lenght;
(void)p_arg;
uint8_t *str =\"加油!\";
,.
位
Show_Str((LED_SET.Width - lenght)/2,0,str); //将要显示的字放到中间部
LedClear(0); //清屏,什么都不显示,只清一个缓存的,这样才会闪烁显示
LedClear(1) }
}
OSTimeDlyHMSM(0,0,0,500);
因篇幅问题不能全部显示,请点此查看更多更全内容