目录

  • 1 项目1  电子琴设计
    • 1.1 课程概述
    • 1.2 蜂鸣器发声
    • 1.3 不同音阶发声和控制
    • 1.4 多功能电子琴
      • 1.4.1 播放一首乐曲的程序编写与仿真
      • 1.4.2 具有多功能电子琴设计与实施
      • 1.4.3 具有多功能电子琴程序编写和仿真
      • 1.4.4 具有多功能电子琴设计--直播程序讲解
  • 2 项目2  LED流水灯设计
    • 2.1 左右依次循环点亮的流水灯设计
    • 2.2 多种花样点亮的流水灯设计
    • 2.3 可调节型多功能亮灯的流水灯设计
  • 3 项目3 直流电机控制
    • 3.1 直流电机的双向转动设计
    • 3.2 转速可调的直流电机转动设计
    • 3.3 多功能直流电机双向转动设计
  • 4 项目4  步进电机控制
    • 4.1 步进电机的双向转动设计
    • 4.2 转速可调的步进电机转动设计
    • 4.3 多功能步进电机双向转动设计
  • 5 项目5 直流电机、步进电机、舵机综合设计
    • 5.1 综合设计
  • 6 项目6 广告灯设计
    • 6.1 在8*8点阵上显示一个字符
    • 6.2 在16*16点阵上显示一个汉字
    • 6.3 在16*16点阵上显示滚动汉字
  • 7 项目7 液晶显示设计
    • 7.1 在1602液晶屏上显示字符
    • 7.2 在1602液晶屏上显示自定义符号和图形
  • 8 电子万年历的制作
    • 8.1 简单万年历的制作
    • 8.2 复杂万年历的制作
    • 8.3 创新万年历的制作
  • 9 作品考核--制作18B20温控风扇
    • 9.1 任务书(拟实现的主要功能)
      • 9.1.1 单片机相关资料
      • 9.1.2 18B20相关资料
      • 9.1.3 PWM脉宽调制资料
      • 9.1.4 74H573介绍
      • 9.1.5 数码管介绍
    • 9.2 原理图、PCB图、焊接图、仿真图
    • 9.3 程序
在16*16点阵上显示滚动汉字

1、在16*16点阵上滚动显示汉字



2、在16*16点阵上滚动显示汉字--程序编写


3、在16*16点阵上滚动显示汉字--仿真演示


参考程序:

/*********************************************************************

修改时间:2020年4月22日19:42

功能:16*16LED点阵显示

目的:用两种滚动模式显示”安徽工商职业学院“

显示方式:列扫描方式

取模软件:PCtoLCD2002完美版

**********************************************************************/

#include  <reg52.h>


#define uchar  unsigned char

#define uint  unsigned int 


sbit  datal595=P1^0;   //列数据线

sbit  datah595=P1^1;   //行数据线

sbit  clk595=P1^2;   //数据输入时钟线

sbit  str595=P1^3;   //输出存储器锁存时钟线

sbit  oe595=P1^4;   //oe输出使能


//取模方式:阴码、逐列式、逆向、十六进制、C51格式自定义 (使用Pctolcd2002软件)

uchar  code  displaydata[]=              //在ROM中定义一个可变长度数组,供用户填充一定个数的字模

{ //可填充的最大字模数取决于您所选用的单片机ROM空间大小

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,0x40,0x00,0x30,0xFC,0x0F,0x04,0x40,0x44,0x40,0x84,0x41,0x04,0x4E,0x25,0x40,

0xC6,0x40,0x04,0x63,0x04,0x50,0x04,0x4C,0x04,0x43,0xE4,0x40,0x04,0x40,0x00,0x00,/*"应",0*/


0x00,0x80,0x00,0x60,0xFE,0x1F,0x22,0x02,0x22,0x02,0x22,0x02,0x22,0x02,0xFE,0x7F,

0x22,0x02,0x22,0x02,0x22,0x42,0x22,0x82,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,/*"用",1*/


0x00,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0xFC,0x3F,

0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x00,0x20,0x00,0x00,/*"工",2*/


0x24,0x08,0x24,0x06,0xA4,0x01,0xFE,0xFF,0x23,0x01,0x22,0x06,0x00,0x40,0x3E,0x49,

0x22,0x49,0x22,0x49,0x22,0x7F,0x22,0x49,0x22,0x49,0x3E,0x49,0x00,0x41,0x00,0x00,/*"程",3*/



//至此字模插入结束

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

};


/*----------------------------------

函数名字:delay_ms

形式参数:无字符整型 i:延时多少

函数功能:以1ms为单位的函数延时

返 回 值:无

------------------------------------*/

void  delay_ms(uint i)                      

{

    uint j;

for(;i>0;i--)

for(j=110;j>0;j--);

}


/*----------------------------------

函数名字:senddata 

形式参数:无字符整型 datah:行的数据 

  无字符整型 datal:列的数据

函数功能:把数据发送给芯片74HC595

返 回 值:无

------------------------------------*/

void  senddata(uint datah,uint datal)         //向行和列的4个595同时发送数据,显示其中的一列数据

{

    uchar i=0;

uint m,n;

oe595=0;

str595=0;

for(;i<16;i++)                       //行和列各有两片595驱动,所以行和列分别需要连续送两个字节数据                      

{

    clk595=0;

m=datah;                         //行为高电平驱动

n=~datal;                        //列为低电平驱动

m&=0x8000;

n&=0x8000;

datah595=(bit)m; //在每个clk周期,同时送出行和列的1bit串行数据

datal595=(bit)n;

datah<<=1; 

datal<<=1;

clk595=1;

}

str595=1;                            //一列数据送完,锁存到输出端进行显示

str595=0;

}

/*----------------------------------

函数名字:char_max 

形式参数:无字符字符型 *dat:两个8位数据的第一个数据的地址

函数功能:受到取模软件的限制,需要对字模表的数据进行重新排列

  将两个8位的数据拼成显示所需16位的数据

返回值  :uint:返回排列好的值

------------------------------------*/

uint char_max(uchar *dat)

{

uint l,h;


h = (uint)*(dat+1); //16位中的高字节数据

h <<= 8;

h &=0xff00;

l = (uint)*dat; //16位中的低字节数据

l &= 0x00ff;

return l|h;

}

/*----------------------------------

函数名字:horizontal 

形式参数:无字符字符型 time:字符移动的速度

  无字符字符型 counth:移动全部字符所需的列数

  无符号字符型指针 p:字符显示数据的首地址

函数功能:显示字符水平移动

返回值  :无

------------------------------------*/

void  horizontal(uchar time,uint count,uchar *p)    //水平移动 

{

uint datah,datal;  //datah是行数据,datal是列选通

    uchar  x,y;

uint  z;

    for(z=0;z<count;z++)              //显示字模表中的所有汉字(包括有用字模前后的的清屏数据)

{

for(y=0;y<time;y++)              //该屏数据重复显示time次后刷新,实际上这是水平移动的速度

{

        for(x=0;x<16;x++)            //发送一整屏数据,16个16位            

        {

p += 2;

datah = char_max(p);

datal = 0x0001<<x; //列选通位移到相应的列上进行选通

// datah=~datah;          //去掉此行前面的注释则水平移动程反白显示

senddata(datah,datal);   //将行和列数据发送出去进行一列的显示

    }

p-=32;                       //指针恢复为这个汉字首地址,准备重复显示该屏数据time次

}                                //该屏数据经过了time次的显示,显示数据准备更新

p+=2; //指向了该汉字的下一列,左移一列汉字

} //移动了字模表中的所有汉字,左移过程结束

oe595=1;

}

/*----------------------------------

函数名字: vertical 

形式参数: 无字符字符型 a:半角标志 ;如果 a=16 则字符显示数据中出现了半角字

无字符字符型 time:字符移动的速度

无字符字符型 counth:移动全部字符所需的行数

无符号字符型 指针 p:字符显示数据的首地址

函数功能: 显示字符垂直移动

返回值  :

------------------------------------*/

void  vertical(uchar a,uchar time,uint countv,uchar *p)    //垂直移动

{

uint datah,datal;  //datah是行数据,datal是列选通

    uchar  x,y,e,w=0;

uint  z;

uint  datah1,datah2;  

uchar *q;

q=p+32;               

for(z=countv;z>0;z--)                //显示字模表中的所有汉字(包括有用字模前后的的清屏数据)

{

    for(e=0;e<16;e++)                //拼字的过程,从一个汉字完整地过渡到下一个汉字

{

    for(y=0;y<time;y++)          //该屏数据重复显示time次后刷新,实际上这是垂直移动的速度

{

            for(x=0;x<16;x++)        //发送一整屏数据,16个16位 

            {

    /*处理p所指向汉字某一列的拼接*/

                    p += 2;  

datah1 = char_max(p);

datah1>>=w;           //这行语句改为左移同时下处改为右移,则显示向下移动

/*处理下一个汉字相应列的拼接*/

q += 2;  

datah2 = char_max(q);

datah2 <<= (16-w);     //这行语句改为右移同时上处改为左移,则显示向下移动

/*准备显示这列数据*/

datah = datah1|datah2; //此时进行拼接某汉字某一列的运算操作

datal = 0x0001<<x; //列选通位移到相应的列上进行选通

//datah=~datah;      //去掉此行前面的注释则垂直移动程反白显示 

    senddata(datah,datal); 

        }                        //一整屏数据发送完毕

p-=32;q-=32;             //指针恢复为这个汉字首地址,准备重复显示该屏数据time次

}                            //该屏数据经过了time次的显示,显示数据准备更新

w++;                         //显示上移w行的拼接数据移位位数加1

if(w>=16) w=0;              //如果上移了15行,w归0,结束此次拼字循环

}                                //此次拼字循环结束

/*开始对下一组汉字进行拼字操作*/

if((a==16)&&(z==2))          //如果字模表中含有半个汉字并且显示最后一组汉字

{ p+=32;q+=16; }          //则q+16,相当于用16个零填充不足的半个汉字

else //其它情况下

{ p+=32;q+=32; }                 //p和q一律指向下一个汉字

}                                    //拼完字模表中的所有汉字,上移过程结束(注:上移是现象,拼字是本质)

oe595=1;

}


void  main(void)

{

uchar  time=8;                       //调整这个值的大小将会改变汉字移动的速度

uint  size=sizeof(displaydata);      //计算出上述在ROM中定义的可变长度字模表填充数据后的大小

uint  countv=((size-2)>>5)-1;  // 8  //这些个汉字水平移动全部完成所需要的拼字次数

uint  counth=countv<<4;        //128 //这些个汉字水平移动全部完成所需要的左移列数

uchar  a=(uchar)((size-2)%32);       //判断字模表中是否会出现一个半角的数字或符号或字母

if(a==16)                            //如果余数为16,说明出现了半角情况

{

    counth+=8;                      //这时左移时需要多移动8列

countv+=1;                       //而右移时需要多拼一个汉字

}

while(1)

{

    horizontal(time,counth,displaydata);            //将字模表中的所有汉字进行水平移动

delay_ms(2000);     

vertical(a,time,countv,displaydata);       //将字模表中的所有汉字进行垂直移动

delay_ms(2000);      

    }

}