📄 display_board3.0.c
字号:
/*器件:AVR ATMEGA16、373缩存器、62256K扩展RAM
I/O定义:
SPI接口显示键盘:
PB0: 键盘
PB1: RCK
PB2: SCK
PB3: DATA
SPI屏幕接口& 下载口:
PB4: SS
PB5: DI
PD7: SCK
RAM:
PA0~7: PC0~7 A0~A7地址线
PC2~6: A10~A14地址
PD3~4 A8~A9 地址
PA0~7: DATA总线复用
PD7: ALE
PD6: WE
PD5: RE
下载:
PB4~7: SPI通讯和下载端口
PD0~1: UART通讯口
电机:
PD2: 外中断,电机脉冲
*/
/********************************************************
广告屏程序第二次改版----主显示控制模块程序5.0
1、程序采用模块化构架,提高了可读性
2、此程序支持第二套广告屏硬件
3、改动:显示屏部分用硬件SPI传输,大大的提高了系统传输速率.
4、增加和手机模块的M16的I2C数据通讯,SRAM的A16,A17改动.
创建时间:2004年11月23日
作者:西南科技大学 电子设计大赛第8大组
注意:需要包括 :<disp_key.h>
********************************************************/
/***************************************************
头文件申明
****************************************************/
#include<iom16v.h>
#include<macros.h>
#include"disp_key.h"
/************************************************
宏定义
**************************************************/
//RAM
#define ALE 7 //定义锁存脚
#define WE 6 //定义写允许位
#define RE 5 //定义读允许位
#define START 0X08
#define MT_SLA_ACK 0X18
#define MT_DATA_ACK 0X28
#define MT_SLA_NACK 0x20
#define MT_DATA_NACK 0x30
#pragma interrupt_handler exi_int0:2 //外部中断
#pragma interrupt_handler timer1_vof:9 //定时器1中断
#pragma interrupt_handler usart_rcx:12 //USART接受中断
/************************************************
全局变量申明
**************************************************/
//基本全局变量
int sys_cont =0;
//显示缓冲区
char DispTemp[8];
//按键处理
//数脉冲
int PDataY =0;
int PDataYMax =152;
int PDataYMin =2;
//UART接收数据
char FileEnd =1;
char HeadLoad =0;
char HeadEN =1;
int DataIndex =0;
int FileLength =0;
char Head[3]; //头文件"LED"存储
unsigned int time_out_ms=1; //接收数据时限
unsigned char time_out_s=0; //试图通讯重新时限
//I2C接受
unsigned int I2C_TIME_OUT =0;
//特效处理
char DispModel =0;
int ModelDelayTime =0;
char ModelContJuge=0;
/************************************************
函数申明
**************************************************/
//基本初始化
void port_int(void);
void timer_int(void);
void uart_int(void);
void device_int(void);
void twi_init(void);
//按键显示事件处理
void Display_event(void); //显示事件
void KEY_event(void); //按键事件处理
//特效处理
void Disp_Model(void); //屏幕显示特效模式
//外部RAM读写操作
void data_store(char data);
char RAM_Read(int adress);
void RAM_Write(int adress,char data);
//显示屏数据发送
void Screen_send(void);
//i2c硬件通讯
void twi_send(char data);
//SPI硬件通讯
void SPI_MasterInit(void);
void SPI_MasterTransmit(char cData);
//UART收发数据
void uart_TX(unsigned char data);
void uart_time_out(void);
//中断函数
void exi_int0(void);
void timer1_vof(void);
void usart_rcx(void);
/************************************************
*
* 子函数区
*
*************************************************/
/****************************************
端口定义
****************************************/
void port_int(void)
{
DDRA =0XFF;
PORTA =0XFF;
DDRB =0B11111110;
PORTB =0XFF;
DDRC =0XFC;
PORTC =0XFF;
DDRD = 0xF8; //
PORTD = 0XFF;
}
/****************************************
定时器
****************************************/
void timer_int(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0xd4; //setup
TCNT1L = 0xce;
TCCR1A = 0x00;
TCCR1B = 0x01; //start Timer
TIMSK = 0x04;
}
/****************************************
外中断
****************************************/
void exit_int(void)
{
GICR = 0x40;
MCUCR = 0x02;
}
/****************************************
串口通讯
****************************************/
void uart_int(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = 0x00;
UBRR =5; //设置波特率115200
UCSRB = 0x98; //接受中断允许,接受允许,发送允许
UCSRC = 0xAe; //8BIT, 奇校验,2停止位
}
/****************************************
硬件SPI通讯
****************************************/
void SPI_MasterInit(void)
{
SPCR = 0B01111100; //setup SPI
SPSR = 0B00000001; //setup SPI
}
/****************************************
硬件i2c通讯
****************************************/
// bit rate:1
void twi_init(void)
{
TWCR= 0X00; //disable twi
TWBR= 16 ; //set bit rate
TWSR= 2; //set prescale
TWAR= 0x04; //set slave address
TWCR= 0x44; //enable twi
}
/****************************************
器件初始化函数
****************************************/
void device_int(void)
{
CLI();
port_int();
timer_int();
exit_int();
uart_int();
SPI_MasterInit();
twi_init();
SEI();
}
/****************************************
串口收发数据
****************************************/
void uart_TX(unsigned char data)
{
UCSRA |=0X40; //标志清零
UDR =data;
}
//***************
//传输超时处理,当time_out_ms大于设定值的时候,等待等待20S,并且
//一直发送标志符号,超过20S以后,进行错误处理
void uart_time_out(void)
{
time_out_ms++;
if (HeadEN ==0 && FileEnd ==0 && time_out_ms >=800 )
{
if(sys_cont ==0) //秒记时
{
time_out_s++;
if (time_out_s ==20) //结束标志
{
time_out_ms=1; //闲置标志
HeadEN=1;
FileEnd=1;
//进行错误处理,并要跳出此结构体
{/**********/}
}
}
uart_TX(0xAA); //重复发送标志位
time_out_ms--;
}
if (time_out_ms ==1000)
time_out_ms=1; //1 表示空闲状态
}
/***************************************************
I2C送数据
***************************************************/
void twi_send(char data)
{
start:
I2C_TIME_OUT =0;
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)))
{
if(I2C_TIME_OUT >1000)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
goto start;
}
}
Disp_Buff[7] ++;
if ((TWSR & 0xF8) != START)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
delay(2);
goto start;
}
TWDR = 0x02; //送地址1.主机发送模式
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)))
{
if(I2C_TIME_OUT >1000)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
goto start;
}
}
Disp_Buff[7] =2;
if ((TWSR & 0xF8) != MT_SLA_ACK)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
goto start;
}
TWDR = data; //送数据
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)))
{
if(I2C_TIME_OUT >1000)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
goto start;
}
}
Disp_Buff[7] =3;
if ((TWSR & 0xF8) != MT_DATA_ACK)
{
//goto start;
}
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
/***************************************************
向显示屏送数据
***************************************************/
void Screen_send(void)
{
char i =8;
PORTB &=0B11101111; //送RCK信号,底电平
for(;i >0;)
{
i--;
SPI_MasterTransmit(DispTemp[i]);
}
PORTB |=0B00010000; //关闭RCK信号,高电平
}
//SPI硬件通讯
void SPI_MasterTransmit(char cData)
{
SPDR = cData;/* 启动数据传输 */
while(!(SPSR & (1<<SPIF)));/* 等待传输结束 */
}
/**************************************************
数据接受,外部RAM读写
****************************************************/
//写外部RAM
void RAM_Write(int adress,char data)
{
char High8Bit;
High8Bit=adress >>8;
PORTD |=0B11100000; //关ALE 读关闭 写关闭
PORTC =0;
DDRA =0XFF;
PORTA =adress;
PORTD &=0xe7;
PORTC =High8Bit;
PORTD |=(High8Bit <<3) & 0x18;
PORTD &=0b01111111;
PORTA =data;
PORTD &=0b10111111;
}
//读外部RAM
char RAM_Read(int adress)
{
char High8Bit;
High8Bit=adress >>8;
PORTD |=0B11100000; //关ALE 读关闭 写关闭
DDRA =0XFF;
PORTA =adress;
PORTD &=0xe7;
PORTC =High8Bit;
PORTD |=(High8Bit <<3) & 0x18;
PORTD &=0b01011111;
DDRA =0;
PORTA =0XFF;
return PINA;
}
//存储数据到外部RAM
void data_store(char data)
{
if((data ==76) &&(FileEnd ==1)) //数据起始位检测
{
HeadEN =1; //开启头文件数据传输
HeadLoad =0; //头文件指针清零
DataIndex =0; //存储数据指针清零
}
if((HeadEN ==0) &&(FileEnd ==0))
{
RAM_Write(DataIndex,data); //数组送数
if(DataIndex ==2) //送文件长度数据到变量
{
FileLength =(RAM_Read(0x0001)<<8)|RAM_Read(0x0000);
}
DataIndex++; //数据指针加1
if(((DataIndex >=FileLength)||(DataIndex >=32767))&& (DataIndex >16))
{
HeadEN =1;
FileEnd =1;
}
}
if(HeadEN ==1) //循环检测文件起始标志
{
Head[HeadLoad] =data;
HeadLoad++;
if(HeadLoad ==3)
{
if((Head[0] ==76) && (Head[1] ==69) &&(Head[2] ==68))//文件起始表示吻合
{
HeadEN =0;
FileEnd =0;
}
}
}
}
/**************************************************
显示效果处理
****************************************************/
void Disp_Model(void)
{
unsigned int file_length =0;
int PYMax =FileLength >>8;
//DispModel =RAM_Read(2) & (RAM_Read(3)<<8); //model控制字节
//PFileMax =(RAM_Read(0) & RAM_Read(1)<<8)>>3; //计算缓冲区域的最大列数
if(ModelDelayTime ==0)
{
switch(DispModel)
{
case 0:
{ //基本显示
PDataYMin =2;
PDataYMax =152;
break;
}
case 1:
{ //滚屏
PDataY++;
break;
}
case 2:
{ //反向滚屏
PDataY--;
break;
}
case 3:
{
break;
}
case 4:
{ //覆盖模式
if(ModelContJuge ==1)
{
PDataYMax++;
PDataYMin++;
}
else
{
PDataYMax--;
PDataYMin--;
}
if(PDataYMax >302)//PYMax)
{
ModelContJuge =0;
}
if(PDataYMin <2)
{
ModelContJuge =1;
}
break;
}
case 5:
{
break;
}
}
//ModelDelayTime =RAM_Read(4) & (RAM_Read(5)<<8);
ModelDelayTime =30;
}
}
/**************************************************
按键\显示事件处理区
****************************************************/
void KEY_event(void)
{ /********* 添加按键处理代码 ***************/
switch(key_num)
{
case 0:
{//And your code
Disp_Buff[2] =!Disp_Buff[2];
break;
}
case 1:
{
break;
}
case 2:
{
break;
}
case 3:
{
DispModel++;
if(DispModel >8)
DispModel =0;
break;
}
/*..................*/
}
}
// 显示事件添加
void Display_event(void)
{ /************* 添加显示 ***********************/
}
/******************* 结束 ***********************************/
/********** 主函数区 *****************************/
void main(void)
{
char temp =0;
device_int();
while(1)
{
if(Disp_Buff[2] !=0)
{
Disp_Buff[0] =temp &0x0f;
Disp_Buff[1] =temp >>4;
twi_send(temp++);
delay(5);
}
}
}
/************ 中断函数区 *************************/
/************************************
外中断
数电机脉冲
*************************************/
void exi_int0(void)
{
char i =0;
int adress;
adress =PDataY<<3; //列地址转化为存储地址
for(;i <8;i++)
{
DispTemp[i] =RAM_Read(adress++);//地址偏移,取数到显示缓冲区
}
Screen_send(); //送显示屏幕数据
PDataY++;
if(PDataY >= PDataYMax) //数据定位
PDataY =PDataYMin ;
}
/*******************************************
定时器中断
系统主要时钟基准
********************************************/
void timer1_vof(void)
{
SEI();
TCNT1H = 0xd4; //setup
TCNT1L = 0xce;
sys_cont++; //系统调用时间变量
if(sys_cont ==1000)
sys_cont =0;
if(key_delay >0) //键盘去抖动延时变量
key_delay--;
if(delay_time_count >0)
delay_time_count--; //ms延时用变量
if(ModelDelayTime >0) //模式切换时间
ModelDelayTime--;
I2C_TIME_OUT++;
if(I2C_TIME_OUT ==2000)
I2C_TIME_OUT ==0;
Disp_key_group(); //显示刷新,取键值到缓冲区
Key_num(); //键值后期处理以及去抖函数
Disp_Model(); //屏幕显示特效模式
KEY_event(); //按键事件处理
Display_event(); //显示事件
//twi_send(sys_cont);
}
/*************************************
USART 接受中断
******************************/
void usart_rcx(void)
{
unsigned char uart_data;
uart_data =UDR;
data_store(uart_data);//存储数据
uart_TX(0xAA); //返回数据
time_out_ms=0; //超时毫秒计数
time_out_s=0; //超时秒计数
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -