|
/***********************************************
16x32点阵屏16级灰度显示
单片机:STC12C5616AD
程序原创:徐长伟
时间:2015/08/03
//分五场扫描增加亮度,全高PWM扫三场,1/2PWM一场,1/4PWM一场
//每个char数据存两个点的数据以节约空间
***********************************************/
#include<STC12C56.H>
#include"mydef.h"
#include"init.h"
/********延时函数2***********/
void delay(uint a)
{
uint c;
for(c=0;c<50000;c++)
for(;a>0;a--);
}
/********清0函数***********/
void delete ()
{
uchar m,n;
for(m=0;m<16;m++)
{
for(n=0;n<16;n++)
{
dispram[n+m*16]=0;
disphuan[n+m*16]=0;
}
}
}
/********串口发送函数***********/
void UART_Send (uchar dat)
{
TI=0;
SBUF=dat;
while(!TI);
TI=0;
}
/********灰度修正函数***********/
void huidu_chuli ()
{
uint i;
uchar x,y;
for(i=0;i<256;i++)
{
x=dispram[i]&0xf0;
y=dispram[i]&0x0f;
x>>=4;
//if(x>0&&x<15)
x-=4;
//if(y>0&&y<15)
y-=4;
if(x>15)x=0;
if(y>15)y=0;
dispram[i]=0;
dispram[i]=x<<4;
dispram[i]|=y;
}
for(i=0;i<256;i++)
{
x=disphuan[i]&0xf0;
y=disphuan[i]&0x0f;
x>>=4;
//if(x>0&&x<15)
x-=4;
//if(y>0&&y<15)
y-=4;
if(x>15)x=0;
if(y>15)y=0;
disphuan[i]=0;
disphuan[i]=x<<4;
disphuan[i]|=y;
}
}
/********74HC595移位寄存器送数子函数***********/
/*
void song(uchar z,uchar y)//带参数函数
{
uchar num;//定义变量
for(num=0;num<8;num++)//移动8次将数据发送完毕
{
CLK=0;//上升沿送走数据
if(z&0x01==1)//将高7位屏蔽掉,保留最低位判断 ////////上半屏(右半屏)
DATA=1;//为1就将74HC595数据端置1
else
DATA=0;//否则给0
if(y&0x01==1)//将高7位屏蔽掉,保留最低位判断 ////////下半屏(左半屏)
DATA_TOP=1;//为1就将74HC595数据端置1
else
DATA_TOP=0;//否则给0
CLK=1;//高电平形成上升沿
z>>=1;//将数移走一位
y>>=1;
}
}
*/
/********灰度分场处理函数***********/
void huidu ()
{
static uchar k,l,s,ss,v,num;
uchar temp,temp1,temp2;
v=hang;//下一行
for(k=0;k<32;k++)
{
Gray[k]=0;//清除内存
}
for(num=0;num<4;num++)//每次存一行的点的全部4BIT(权*N,N=0~3)灰度值
{
for(k=0;k<4;k++)//Gray数组里每个字节存4个点的权*N位灰度值,32行点阵分为16行*2,所以要4*2=8个字节
{
s=8;
for(l=0;l<4;l++)//Gray里每个字节存两个点的灰度值(16级灰度来说)每次存两个点的各一位灰度(即两位)循环4次就是8位
{
ss=s-1;
temp2=l+(k<<2)+(v<<4);
temp=dispram[temp2];//把内存里数据依次调出
temp1=disphuan[temp2];//把内存里数据依次调出
Gray[k+(num<<3)]|=((temp>>p)&0x01)<<ss;//右移4位后数据高4位的后半字节依次将BIT4-BIT7右移
Gray[k+4+(num<<3)]|=((temp1>>p)&0x01)<<ss;
p-=4;//右移指针等于0处理前半字节
s--;//左移指针减一以便依次将每一组BIT位从高位至低位顺序存入Gray[k]
ss=s-1;
Gray[k+(num<<3)]|=((temp>>p)&0x01)<<ss;//右移0位后数据低4位的数据前半字节依次将BIT0-BIT3右移
Gray[k+4+(num<<3)]|=((temp1>>p)&0x01)<<ss;
p+=4;//右移指针等于4处理后半字节
s--;//左移指针再减一
}
}
p++;//将数据灰度值右移一位(第0BIT直到第3BIT)
}
p=4;//右移4位后复位到4
}
/***************串口初始化函数*****************/
void UART_OK ()
{
CCAPM1=0X00;
P3M0=0x00;
P3M1=0x00;
SCON=0X40;//串口方式1/REN=0
PCON=0X80;// 波特率倍增
TMOD = 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1= 0xFD; // TH1: 重装值 57600 波特率 晶振 33.1776MHz
TL1= 0xFD;
TR1= 1; // TR1: timer 1 打开
PPCA_LVD=0;
EPCA_LVD=0;
ES=0;
REN=1;
PS=1;
IPH|=~PPCA_LVDH;
EA=1;
TR0 = 0;
}
/***************主函数*****************/
void main()
{
uchar n;
//Init();
delay(3000);
UART_OK();
CCAP1L=PWM_1_8;
CCAP1H=PWM_1_4;
qie=0;
while(1)
{
if(!flag_es_ok)
{
while(aa!=_READY_) //从机等待主机发送的握手信号
{
UART_Send (_STAR_);
if(RI)
{
aa=SBUF;
RI=0;
}
}
UART_Send (_OK_);
ES=1;
}
check=255;//数据校验初值
while(!flag_es_ok);
if(!flag_es_init) huidu_chuli ();//灰度修正
if(!flag_es_init){flag_es_init=1;Init();}
if(qie==TIME_1)
{
LED=1;
aa=_BUSY_;
flag_es_init=0;
flag_es_ok=0;
ISP_CONTR|=SWRST;//软复位
}
if(flag_zhen)//如果一帧扫描完就右移一次
{
flag_zhen=0;
if(++hang==16)//显示16行
{
hang=0;
qie++;
}
}
if(flag_qie){flag_qie=0;huidu ();}//灰度分解
if(flag_chang)////每场进入一次/如果一场扫描完再切到下一行避免虚影
{
if(flag_es_ok)
{
for(n=8;n>0;n--)//lienum=595片数//595片数=6以上显示才稳定song(~Gray[n-1],~Gray[n+3]);
{
if(n>4)
{
_datu=~Gray[n-5+(t<<3)];
_datd=~Gray[n-1+(t<<3)];
DATA=_datu0;
DATA_T |
|