⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 AVR单片机ATMEGA32驱动240*128LCD程序
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include "HZ.h"
#include "T6963.h"
#include "head.h"
//宏定义区///////////////////////////////////////////////////////////////
#define V_MAX	2000
#define A_MAX	5000
#define TE_MAX	999
#define TI_MAX	1999
#define CA_MAX	9999
#define B_MAX	999
#define DMAX	9999
#define VSADDR	0x0000
#define CSADDR	0x0002
#define TESADDR	0x0004
#define TISADDR	0x0006
/////////////////////////////////////////////////////////////////////////
//全局变量区/////////////////////////////////////////////////////////////

unsigned char	WorkStatus		= 0x00;//有限状态机
unsigned char	TimeOut			= 0x0A;//通信超时
unsigned char	CPage			= 0x00;//当前显示缓冲区首地址
unsigned char	N_step			= 0x00;//当前步
unsigned char N_cycle			= 0x00;//当前周
unsigned char Stepchange		= 0x00;
unsigned char number			= 0x01;
unsigned char S_number[10];
unsigned char S_state 			= 0xf0;
unsigned char m_page			= 0x00;
unsigned int XS_state[10];
unsigned char N_flag			= 0x00;
unsigned char dis_fige			= 0x00;
unsigned int  NS_state			= 0x0000;
unsigned int	Work_commend	= 0x0000;//工作命令,传给下位机
unsigned int	Voltage			= 0x0000;//实际电压72.00V
unsigned int	Current			= 0x0000;//实际电流300.0A
unsigned int	ACurrent[10];
unsigned int	Temp			= 0x0000;//实际温度099.9C
unsigned int	Time			= 0x0000;//实际时间999M
unsigned int	Capacitor		= 0x0000;//实际容量
unsigned int	CVoltage;//恒压72.00V
unsigned int	XVoltage[10];//恒压72.00V
unsigned int	CCurrent;//恒流300.0A
unsigned int	XCurrent[10];//恒流300.0A
unsigned int	StopCurrent;//涓流
unsigned int	XStopCurrent[10];//涓流
unsigned int	StopVoltage;//电压
unsigned int	StopTemp		= 0x0000;//停止温度099.9C
unsigned int	StopTime;//停止时间999M
unsigned int	XStopTime[10];//停止时间999M
unsigned int	BackLight		= 0x0000;//背光亮度
unsigned int	StopCapacitor;//停止容量
unsigned int	XStopCapacitor[10];//停止容量
unsigned int	LowStatus		= 0x0000;//下位机状态
unsigned int	TempValue		= 0x0000;//键盘输入临时值
/////////////////////////////////////////////////////////////////////////
//自编函数区/////////////////////////////////////////////////////////////
unsigned char EEPROM_read(unsigned int uiAddress);
void EEPROM_write(unsigned int uiAddress, unsigned char ucData);
void vDataInit(void);
void vSetPara(void);
void vGetInt(unsigned char key);
void vWork(void);
void vStop(void);
void vWait2Ensure(void);
void vSetup(void);
void vCheck(void);
void vDisplay(void);
void vSet_state(unsigned char op);
void vMenu(unsigned char key);
void vWait(unsigned int us);
//void wait_m(unsigned int ms_)
void vWrite(unsigned char data);
unsigned char ucRead(void);
char LCD_StatusCheck(unsigned char mask);
char LCD_WriteCommand(unsigned char cmd);
char LCD_WriteData(unsigned char dat);
char LCD_AutoWriteData(unsigned char dat);
unsigned char LCD_ReadStatus(void);
unsigned char LCD_ReadData(void);
unsigned char LCD_AutoReadData(void);

char LCD_INIT(void);
char LCD_FILL(unsigned char page,unsigned char dat);
char LCD_LOAD_PAGE(unsigned char page,const unsigned char *p);
char LCD_PutChar(unsigned char page,unsigned int position,const unsigned char *hz);
char LCD_PutEng(unsigned char page,unsigned int position,const unsigned char *hz);
char LCD_PutAnyThing(unsigned char page,unsigned int position,unsigned char dat);
char LCD_Case(unsigned char page);
char LCD_Case1(unsigned char page);
void vLCD_Page_Change(unsigned char page);


void LCD_page0(void);//logo
void LCD_page1(void);//real
void LCD_page2(void);//c/v
void LCD_page3(void);//tt
void AVE_current(void);
void DisNum(unsigned int nm,unsigned char tp);
unsigned char cKeyScan(void);
unsigned char cKey(unsigned char keyval);//按键

/////////////////////////////////////////////////////////////////////////
//系统函数区/////////////////////////////////////////////////////////////
void vPortInit(void);
void vInit(void);
void vTimer0Init(void);
void vOCR1Init(void);
void vSpiInit(void);
void vTWInit(void);
void wait(unsigned int time)					//延时
{
	unsigned int i;
	unsigned char j;
	for(i=0;i<time;i++){
		for(j=0;j<6;j++){
				__asm__("	WDR");

		}
	}
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

int main(void)
{
	unsigned int ms = 0;
	unsigned int msa = 0;
	unsigned int msb = 0;
	unsigned int msc = 0;
	unsigned int msf = 0;
	unsigned int msg = 0;
	volatile unsigned char null = 0;
	unsigned char ka = 0,kb = 0;
//	unsigned char k = 0;
//	const unsigned char *p = name;
	vInit(); //初始化片内设备
	null = LCD_INIT();//LCD初始化
	vLCD_Page_Change(1);
	wait(10000);
	wait(10000);
	wait(10000);

	vDataInit();
	vDisplay();
	//vLCD_Page_Change(1);
	//vLCD_Page_Change(2);
	while(1)
	{
		__asm__("	WDR");
		if(TIFR&(1<<OCF0))//1KHz---1000us
		{
			TIFR |=1<<OCF0;
			ms +=1;
			if(TimeOut>0)TimeOut--;			
			if(ms >3999)ms=0;
		}
		if(((ms%2000)==99)&&(msf!=ms))
		{
			msf=ms;
			msg++;
			if(msg>10)
			{
				LCD_page1();
				LCD_page2();
				msg=0;
			}
		}
		
		if(((ms%20)==5)&&(msa!=ms))
		{
			msa = ms;
			//TODO: the code below will be execute every 30ms
			ka = cKey(cKeyScan());
			if(kb != ka)
			{
				kb = ka;
				if(kb < 0x14)vMenu(kb);
			}
			vSetPara();
			if((LowStatus&0x00ff)==0x0009)
			{
				if(Stepchange==0x0f)Stepchange=0x00;
			}
			if((LowStatus&0x00ff)==0x0021)
			{
				if(Stepchange==0x00)	
				{
					Stepchange=0x0f;	
					N_step			= N_step+1;
					NS_state		= XS_state[N_step];	
					CVoltage		= XVoltage[N_step];
					CCurrent		= XCurrent[N_step];
					StopCurrent		= XStopCurrent[N_step];
					StopTime		= XStopTime[N_step];
					StopCapacitor	= XStopCapacitor[N_step];
					N_flag			=	S_number[N_step];					
					WorkStatus = 0x30;
					vWork();
					dis_fige=1;
					
					if(NS_state==0)
					{
						WorkStatus = 0x10;
						Work_commend=0xff00;
						vStop();
						dis_fige=0;
					}
					if(NS_state==5)
					{
						N_step		= 	N_flag-1;
						N_cycle++;
						WorkStatus	= 0x12;	
					}
				}
			}
		}
		if(((ms%100)==15)&&(msb!=ms))
		{
			msb = ms;
			//TODO: the code below will be execute every 100ms
			DisNum(0,0);
		}
		if(((ms%10)==3)&&(msc!=ms))
		{
			msc = ms;
			AVE_current();
		}
	}
	return(-1);
}
//////////////////////////////////////////////////////////////////////
void vDisplay(void)
{
	DisNum(0,0);
	DisNum(XVoltage[number],5);
	DisNum(XCurrent[number],6);
	DisNum(XStopCurrent[number],7);
	DisNum(XStopTime[number],8);
	DisNum(XStopCapacitor[number],9);
	DisNum(S_number[number],10);
	vSet_state(XS_state[number]);
}
//中断服务函数区/////////////////////////////////////////////////////////
/*ISR(SPI_STC_vect)
{
	
	unsigned char val = 0x00;
	unsigned int tout= 0X0000;
	val=SPSR;
	val = SPDR;
	SPDR=0x55;	
}*/
ISR(SPI_STC_vect)
{
	volatile static unsigned char bn = 0xff;
	static unsigned char kk = 0x00;
	static unsigned char k  = 0x00;
	static unsigned char mp  = 0x00;
	unsigned char val = 0x00;
	
	val = SPDR;
	if(TimeOut == 0)
	{
		bn = 0;
	}
	switch(bn)
	{
		case 0:
		{
			k = val;
			switch(k)
			{
				case 0:
				{
					SPDR =	Work_commend%0x100;//发送命令的低字节
				}break;
				case 1:
				{
					SPDR =	StopCurrent%0x100;//发送涓流电流
				}break;
				case 2:
				{
					SPDR =	CVoltage%0x100;//发送恒压
				}break;
				case 3:
				{
					SPDR =	CCurrent%0x100;//发送恒流
				}break;
				case 4:
				{
					SPDR =	StopTemp%0x100;//发送温度上限
				}break;
				case 5:
				{
					SPDR =	StopTime%0x100;//发送时间上限
				}break;
				case 6:
				{
					SPDR = StopCapacitor%0x100;//发送容量上限
				}break;
				case 7:
				{
					SPDR = NS_state%0x100;//发送停止电压
				}break;
				case 8:
				{
				}break;
				default: break;
			}
		}break;
		case 1:
		{
			switch(k)
			{
				case 0:
				{
					SPDR =	Work_commend/0x100;//发送命令的高字节
					kk	= val;
				}break;
				case 1:
				{
					SPDR =	StopCurrent/0x100;//发送涓流电流
					kk	= val;
				}break;
				case 2:
				{
					SPDR = CVoltage/0x100;	//发送恒压
					kk = val;
				}break;
				case 3:
				{
					SPDR = CCurrent/0x100;	//发送恒流
					kk = val;
				}break;
				case 4:
				{
					SPDR = StopTemp/0x100;	//发送温度上限
					kk = val;
				}break;
				case 5:
				{
					SPDR = StopTime/0x100;	//发送时间上限
					kk = val;
				}break;
				case 6:
				{
					SPDR = StopCapacitor/0x100;	//发送容量上限
					kk = val;
				}break;
				case 7:
				{
					SPDR = NS_state/0x100;//发送停止电压
				}break;
				case 8:
				{
					kk = val;
				}break;
				default: break;
			}
		}break;
		case 2:
		{
			switch(k)
			{
				case 0:
				{
					LowStatus = val*0x100+kk;
				}break;
				case 1:
				{
					//FarVoltage =  val*0x100+kk;
				}break;
				case 2:
				{
					Voltage =  val*0x100+kk;
				}break;
				case 3:
				{ 
					ACurrent[mp]=val*0x100+kk;
					if(mp>8)mp=0;
					else mp++;
					
				}break;
				case 4:
				{
					Temp =  val*0x100+kk;
				}break;
				case 5:
				{
					Time =  val*0x100+kk;
				}break;
				case 6:
				{
					Capacitor = val*0x100+kk;
				}break;
				case 7:
				{
				}break;
				case 8:
				{
					//eer_data = val*0x100+kk;
				}break;
				default: break;
			}
		}break;
		default:break;
	}
	if((++bn)>2)
	{
		bn = 0;
		k = 0;
		TimeOut = 0;
	}
	else TimeOut = 10;
}
/////////////////////////////////////////////////////////////////////////
//自编函数区/////////////////////////////////////////////////////////////
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
	while(EECR & (1<<EEWE));/* 等待上一次写操作结束 */
	EEAR = uiAddress;/* 设置地址和数据寄存器*/
	EEDR = ucData;
	EECR |= (1<<EEMWE);/* 置位EEMWE */
	EECR |= (1<<EEWE);/* 置位EEWE 以启动写操作*/
}
/***********************************/
unsigned char EEPROM_read(unsigned int uiAddress)
{
	while(EECR & (1<<EEWE));/* 等待上一次写操作结束 */
	EEAR = uiAddress;/* 设置地址寄存器*/
	EECR |= (1<<EERE);/* 设置EERE 以启动读操作*/
	return(EEDR);/* 自数据寄存器返回数据 */
}

void AVE_current(void)
{
	unsigned char i 		= 0;
	unsigned int  max		= 0;
	unsigned int  min		= 0xffff;
	unsigned long total = 0;
	for(i=0;i<10;i++)
	{
		if(ACurrent[i]>max)max=ACurrent[i];
		if(ACurrent[i]<min)min=ACurrent[i];
		total +=ACurrent[i];
	}
	Current=(total-(max+min))/8;
}
void vDataInit(void)
{
	
	unsigned char i;
	
	for(i=1;i<10;i++)
	{
	XVoltage[i]		=EEPROM_read(2*i);
	XVoltage[i]		+=EEPROM_read(2*i+1)*256;
	if(XVoltage[i]>V_MAX)XVoltage[i] = 0;//加载恒压
	}
	for(i=1;i<10;i++)
	{
	XCurrent[i]		= EEPROM_read(2*i+20);
	XCurrent[i]		+= EEPROM_read(2*i+21)*256;
	if(XCurrent[i]>A_MAX)XCurrent[i] = 0;//加载恒流
	}
	for(i=1;i<10;i++)
	{
	XStopCurrent[i]	= EEPROM_read(2*i+40);
	XStopCurrent[i]	+= EEPROM_read(2*i+41)*256;
	if(XStopCurrent[i]>A_MAX)XStopCurrent[i] = 0;//加载涓流
	}	
	for(i=1;i<10;i++)
	{
	XStopTime[i]	= EEPROM_read(2*i+60);
	XStopTime[i]	+= EEPROM_read(2*i+61)*256;
	if(XStopTime[i]>TI_MAX)XStopTime[i] = 0;//加载停止时间
	}		
	for(i=1;i<10;i++)
	{
	XStopCapacitor[i]	= EEPROM_read(2*i+80);
	XStopCapacitor[i]	+= EEPROM_read(2*i+81)*256;
	if(XStopCapacitor[i]>CA_MAX)XStopCapacitor[i] = 0;//加载停止容量
	}
	for(i=1;i<10;i++)
	{
		XS_state[i]= EEPROM_read(i+102);
	}
	for(i=1;i<10;i++)
	{
		S_number[i]= EEPROM_read(i+112);
	}
		
}
void vGetInt(unsigned char key)
{
	unsigned int k = 0;
	if(key >0x09)
	{
		TempValue = 0;
		return;
	}
	if(WorkStatus==0x25)k = TempValue%100;//温度99.9
		else k = TempValue%1000;
	k *= 10;
	k += key;
	TempValue = k;
}
void vMenu(unsigned char key)
{
	if(key>0x14)return;
	switch(WorkStatus)
	{
		case 0x00://上电,显示LOGO,按任意键继续
		{
			if(key<0x14)
			{
				WorkStatus = 0x10;//待机状态
				DisNum(0,0);
				vLCD_Page_Change(1);//切换到数据显示页面
				m_page=1;
				vStop();
				dis_fige=0;
			}
		}break;
		case 0x10://待机状态
		{
			if(key==F2)//启动,需要等待确认(需要确定工作参数合理)
			{
				if((LowStatus&0x00ff)==0x0001)
				{
					WorkStatus = 0x11;
					vWait2Ensure();
				}
			}
			if(key==F1)//设定参数
			{
				WorkStatus = 0x20;
				vWait2Ensure();
			}
			CVoltage		= XVoltage[1];
			CCurrent		= XCurrent[1];
			StopCurrent		= XStopCurrent[1];
			StopTime		= XStopTime[1];
			StopCapacitor	= XStopCapacitor[1];
			NS_state		= XS_state[1];
			N_step			= 1;
			N_cycle			= 1;
		}break;
		case 0x30:
		{
			Work_commend=0x00ff;
			WorkStatus	= 0x12;
			vWork();
			dis_fige=1;
		}break;
		case 0x11://等待确认启动
		{
			if(key==ENTER)//已确定启动
			{
				WorkStatus = 0x12;//工作!
				Work_commend=0x00ff;
				//vLCD_Page_Change(2);//
				vWork();
				dis_fige=1;
			}
			else
			{
				WorkStatus = 0x10;//待机
				vStop();
				dis_fige=0;
			}
		}break;

		case 0x12://工作
		{
			if(key==F3)//停止,需要等待确认
			{
				WorkStatus = 0x13;//确认后停止
				vWait2Ensure();
			}
			if(key==F1)
			{
				WorkStatus = 0x14;//查询工作参数
				vCheck();
				vDisplay();
				vLCD_Page_Change(2);//切换到参数显示页面B
				m_page=2;
			}
		}break;
		case 0x13://等待确认停止
		{
			if(key==ENTER)//已确定停止
			{
				WorkStatus = 0x10;
				Work_commend=0xff00;
				vStop();
				dis_fige=0;
			}
			else
			{
				WorkStatus = 0x12;
				vWork();
				dis_fige=1;
			}
		}break;
		case 0x14://显示工作参数态,按任意键返回工作界面
		{
			
			if(key==RIGHT)//下一页
			{
				if(number>=10)
				{
					number=10;
					break;
				}
				number++;
				vDisplay();
				vSetup();
				break;
			}
			if(key==LIFT)//上一页
			{
				if(number<=1)break;
				number--;
				vDisplay();
				vSetup();
				break;
			}
			if(key==ESC)//取消,进入主界面
			{
				WorkStatus = 0x12;
				//vStop();
				vLCD_Page_Change(1);//切换数据显示页面
				m_page=1;
				break;
			}	
		}break;
		case 0x20:
		{
			if(key==ENTER)//进入编辑模式
			{
				vDisplay();
				vLCD_Page_Change(2);
				m_page=2;
				WorkStatus = 0x26;//状态设置
				S_state	=XS_state[number];
				//DisNum(TempValue,5);
				vSetup();
			}
			else
			{
				WorkStatus = 0x10;//待机
				vStop();
				dis_fige=0;
			}
		}break;
		case 0x26:
		{
			if(key==RIGHT)//下一页
			{
				if(number>=10)
				{
					number=10;
					break;
				}
				number++;
				vDisplay();
				vSetup();
				break;
			}
			if(key==LIFT)//上一页
			{
				if(number<=1)break;
				number--;
				vDisplay();
				vSetup();
				break;
			}
			if(key==ESC)//取消,进入主界面
			{
				WorkStatus = 0x10;
				vStop();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -