stm32点阵移动程序.docx
《stm32点阵移动程序.docx》由会员分享,可在线阅读,更多相关《stm32点阵移动程序.docx(23页珍藏版)》请在冰豆网上搜索。
![stm32点阵移动程序.docx](https://file1.bdocx.com/fileroot1/2023-2/2/0c589251-66e7-4fe5-9936-dfccf20be359/0c589251-66e7-4fe5-9936-dfccf20be3591.gif)
stm32点阵移动程序
此程序是用的flash里面装的字库的方法来做的,可以显示各种字和字符,可以各种移动,左移,右移,上下移动都可以。
以下是该程序的主要代码(所谓的主要代码就是跟移动有关的代码)
/**************************************************************************************************
**程序名称:
LedDisplay(void)
**输入参数:
无
**输出参数:
无
**返回值:
无
**描述:
LED显示板一行显示程序。
此程序读取显示缓存中的数据,并在LED上显示出来。
**注:
此程序显示的字模为纵向取模。
**************************************************************************************************/
voidLedDisplay(void)
{
uint16_toffset_addr;
uint16_tlenght;
uint8_t*data;
//#ifdefOS_TICKS_PER_SEC//如果时钟节拍数定义了,说明要使用ucosII了.
//OS_CPU_SRcpu_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++;//行+1
if(ScanRow==LED_SET.ScanMode)//16
{
ScanRow=0;
}
if(ScanRow==LED_SET.FirstRow)//如果完成一帧扫描,置标志,扫描完16行
{
ScanFlag=1;//只有当ScanFlag=1时,才能切换显示容
}
else
{
ScanFlag=0;
}
//#ifdefOS_TICKS_PER_SEC//如果时钟节拍数定义了,说明要使用ucosII了.
//OS_EXIT_CRITICAL();
//#endif
LedDelay(LED_SET.BlankTime);//消隐时间
if(LED_SET.OnOff==ON)//如果显示屏配置为显示,则开显示
{
if(!
LED_SET.ENMode)
{
LedEn_L();//开显示
}
else
{
LedEn_H();
}
}
}
voidGet_HzMat(unsignedchar*code,unsignedchar*mat,uint8_tsize)
{
unsignedcharqh,ql;
unsignedchari;
unsignedlongfoffset;
#ifOS_CRITICAL_METHOD==3//中断函数被设定为模式3
OS_CPU_SRcpu_sr=0u;
#endif
qh=*code;
ql=*(++code);
if(qh<0x81||ql<0x40||ql==0xff||qh==0xff)//非常用汉字,没有包含在字库
{
for(i=0;i<(size*2);i++)
{
*mat++=0x00;//填充满格
}
return;//结束访问
}
if(ql<0x7f)
{
ql-=0x40;//注意!
}
else
{
ql-=0x41;
}
qh-=0x81;
foffset=((unsignedlong)190*qh+ql)*(size*2);//得到字库中的字节偏移量
#ifdefOS_TICKS_PER_SEC//如果时钟节拍数定义了,说明要使用ucosII了.
OS_ENTER_CRITICAL();
#endif
FlashBusy^=1;
SPI_FLASH_BufferRead(mat,GBK16_ADDR+foffset,32);//从flash中读取
FlashBusy^=1;
#ifdefOS_TICKS_PER_SEC//如果时钟节拍数定义了,说明要使用ucosII了.
OS_EXIT_CRITICAL();
#endif
}
/**************************************************************************************************
**程序名称:
Show_Char(int16_trow,int16_tcol,uint8_tstr,uint8_tback)
**输入参数:
int16_trow显示行坐标
**int16_tcol显示列坐标
**uint8_tstr指定字符
**uint8_tback指示写入字模的显示缓存
**输出参数:
无
**返回值:
无
**描述:
在指定位置显示一个16*8字符。
注:
使用font16x8字库。
**************************************************************************************************/
voidShow_Char(int16_trow,int16_tcol,uint8_tstr,uint8_tback)
{
uint8_ttmprow;
uint8_t*pBuf,*tmp;
uint8_ttmpData,tmptt;
uint8_ti,j;
tmprow=row%8;
//tmpcol=col%8;
if(!
back)//区分两个不同的缓存
{
tmp=Buf0;
}
else
{
tmp=Buf1;
}
tmptt=str-32;
for(j=0;j<2;j++)
{
for(i=0;i<8;i++)
{/*判断溢出条件,在这里行可以到-15去*/
if(((row+j)=0)&&((col+i){
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=tmpData;
pBuf+=LED_SET.Width;
tmpData=*pBuf;
tmpData&=0x00;
tmpData|=(~font16x8[tmptt*16+8*j+i])<<(8-tmprow);
*pBuf=tmpData;
}
else
{
tmpData=*pBuf;
tmpData&=0xff<<(8-tmprow);
tmpData|=0xff>>tmprow;
tmpData&=(~font16x8[tmptt*16+8*j+i])>>tmprow;
*pBuf=tmpData;
}
}
elseif((row>=8)&&(row<16))
{
if(j==0)
{
tmpData=*pBuf;
tmpData|=0xff;
*pBuf=tmpData;
pBuf+=LED_SET.Width;
tmpData=*pBuf;
tmpData&=0x00;
tmpData|=(~font16x8[tmptt*16+8*j+i])>>tmprow;
*pBuf=tmpData;
}
}
elseif((row>-8)&&(row<=0))
{
if(j==1)
{
tmpData=*pBuf;
tmpData&=0x00;
tmpData|=(~font16x8[tmptt*16+8*j+i])<<-tmprow;
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));
*pBuf=tmpData;
}
}
elseif((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])<<-tmprow;
tmpData|=0xff>>(8+tmprow);
*pBuf=tmpData;
}
}
}
}
}
}
/**************************************************************************************************
**程序名称:
voidShow_HZ(int16_trow,int16_tcol,uint8_t*hzk,uint8_tback)
**输入参数:
int16_trow显示行坐标
**int16_tcol显示列坐标
**uint8_t*hzk指向指定汉字码的指针
**uint8_tback指示写入字模的显示缓存
**输出参数:
无
**返回值:
无
**描述:
在指定位置显示一个16*16汉字。
注:
使用GBK16字库。
**************************************************************************************************/
voidShow_HZ(int16_trow,int16_tcol,uint8_t*hzk,uint8_tback)
{
uint8_tdzk[32];
uint8_t*pBuf,*tmp;
uint8_ttmprow;
uint8_ttmpData;
uint8_ti,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)=0)&&((col+i){
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=tmpData;
pBuf+=LED_SET.Width;
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);//将高位清零,低位放的是原来高位的
*pBuf=tmpData;
}
//else
//{
//tmpData=*pBuf;
//tmpData&=0xff<<(8-tmprow);//全部清零
//tmpData|=0xff>>tmprow;//高位不变,低位全为1
//
//tmpData&=~(dzk[2*i+(j%2)]>>tmprow);//将高位清零,低位放的是原来高位的
//*pBuf=tmpData;
//}
}
elseif((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;
}
}
elseif((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));
*pBuf=tmpData;
}
}
elseif((row>-16)&&(row<=-8))
{
if(j==1)
{
tmpData=*pBuf;
tmpData|=0xff;
*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_tx,int16_ty,uint8_t*str,uint8_tback)
**输入参数:
int16_ty显示行坐标
**int16_tx显示列坐标
**uint8_t*str指向字符串的指针
**输出参数:
无
**返回值:
无
**描述:
在指定位置开始显示一个字符串。
(x,y):
起始坐标。
**************************************************************************************************/
voidShow_Str(int16_tx,int16_ty,uint8_t*str)
{
int16_tx0=x;
int16_ty0=y;
uint8_tbHz=0;//字符或者中文
uint8_tforget_back;
/*检测显示缓存位置,不允许写入正在显示的缓存*/
if(BackFlag)//BackFlag前后台标志,初始值为1
{
forget_back=0;//前台
}
else
{
forget_back=1;//后台
}
LedClear(forget_back);//清空要写入的缓存
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,