AVR MEGA16A USART ADC PWM IO读取,双色点阵,1602,五向摇杆等综合性代码,初学者慎入。

前言

此文章供于大家参考学习,一起进步。

实现功能

开机后,LCD1602 第一行按秒显示更新系统运行累计时间。显示形式如下(00:00)前两位为分钟,后两位为秒。
开机后,点阵显示数字“0”。
按下K1-K8,点阵(8*8)分别显示数字1-8。
遥杆向上推,打开串口使能,同时上位机(电脑)发送数据给单片机“Forward”,让LCD1602在第二行前半部分显示该数据。
遥杆向下推,关闭串口使能,上位机(电脑)无法发送数据给单片机,此时让LCD1602在第二行前半部分显示“USARTCLOSE”。
遥杆向中按下,打开AD转换,同时显示采集JP25输出电压值,保留小数点一位,LCD1602在第二行显示后半部分实时显示采集电压值,同时控制L9呈现呼吸灯的状态。

代码

/*
 * topic_1.c
 *
 * Created: 2020/5/18 9:17:46
 * Author : zjlc
 * k1-k8 接 PC0-PC7|1602数据口-PB0-PB8|1602控制口-PD1-PD3 RS RW EN|串口接收PD0|LED呼吸灯PD7|双色点阵(三hc595驱动)-PA1-PA6(SHCP,STCP,DS.SHCP,STCP,DS)|PA0-ADC采集|
 */ 

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define  F_CPU 8000000
#define  sreg _SFR_IO8(0x3f)
#define SETSH PORTA |=(1<<1);
#define CLRSH PORTA &=~(1<<1);
#define SETST PORTA |=(1<<2);
#define CLRST PORTA &=~(1<<2);
#define SETDS PORTA |=(1<<3);
#define CLRDS PORTA &=~(1<<3);

#define SETSH_COLOR PORTA |=(1<<4);
#define CLRSH_COLOR PORTA &=~(1<<4);
#define SETST_COLOR PORTA |=(1<<5);
#define CLRST_COLOR PORTA &=~(1<<5);
#define SETDS_COLOR PORTA |=(1<<6);
#define CLRDS_COLOR PORTA &=~(1<<6);

#define rs  1
#define rw  2
#define en  3
#define setrs() PORTD |=(1<<rs)
#define setrw() PORTD |=(1<<rw)
#define seten() PORTD |=(1<<en)
#define clrrs() PORTD &=~(1<<rs)
#define clrrw() PORTD &=~(1<<rw)
#define clren() PORTD &=~(1<<en)

#define uint unsigned int 
int number=5000;
int volue=0;
int now=0;
int adc_new;
float adc_transient;
int T0_frequency=0,time_system_1=0,time_system_2=0;
char bit[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
char usart[10];
char close[]="USARTCLOSE";
void hungray()
{
	DDRB=0x00;
	clrrs();
	setrw();
	seten();
	_delay_us(5);
	while((PINB&0x80)&&(number--));
	clren();
	DDRB=0xff;
}
void write(char data,int or)
{
	hungray();
	PORTB=data;
	if(or==0)
	{
		clrrs();
	}
	else
	{
		setrs();
	}
	clrrw();
	seten();
	clren();
}
void move(int x,int y)
{
	if(x==0)
	write(0x80|y,0);
	if(x==1)
	write(0xc0|y,0);
}
void display(int x,int y,char data)
{
	move(x,y);
	write(data,1);
}
void dis_string(int x,int y,char *data)
{
	move(x,y);
	while(*data!='\0')
	{
		write(*data,1);
		data++;
	}
}
void init()
{
	write(0x38,0);
	_delay_ms(20);
	write(0x0c,0);
	_delay_ms(20);
	write(0x01,0);
	_delay_ms(20);
}
void hc_595_COLOR(char data)
{
	for(uint i=0;i<8;i++)
	{
		if(data&0x80)
		{
			SETDS_COLOR;
		}
		else
		{
			CLRDS_COLOR;
		}
		CLRSH_COLOR;
		SETSH_COLOR;
		data<<=1;
	}
}
void hc_595(char data)
{
	for(uint i=0;i<8;i++)
	{
		if((data&0x80)==0x80)
		{
			SETDS;
		}
		else
		{
			CLRDS;
		}
		CLRSH;
		SETSH;
		data<<=1;
	}
}
void led_2(char red,char green,char sorting)
{
	hc_595_COLOR(green);
	hc_595_COLOR(red);
	CLRST_COLOR;
	SETST_COLOR;
	hc_595(sorting);
	CLRST;
	SETST;
}
void lattice()
{
	for (int i=0;i<8;i++)
	{
		if (!(PINC&bit[i]))
		{
			_delay_ms(20);
			if (!(PINC&bit[i]))
			{
				volue=i+1;
			}
			while (!(PINC&bit[i]));
		}
	}
	
	switch (volue)
	{
		case 0:led_2(0xc3,0xff,0x01);_delay_ms(1); led_2(0xfb,0xff,0xff);_delay_ms(1);led_2(0xdf,0xff,0xff);_delay_ms(1);led_2(0xc3,0xff,0x80);_delay_ms(1);break;//led_2(0xff,0xc3,0x01); led_2(0xff,0xfb,0xff);led_2(0xff,0xdf,0xff);led_2(0xff,0xc3,0x80);
		case 1:led_2(0xef,0xff,0x01);_delay_ms(1); led_2(0xe7,0xff,0x02);_delay_ms(1);led_2(0xef,0xff,0xff);_delay_ms(1);led_2(0xc3,0xff,0x80);_delay_ms(1);break;
		case 2:led_2(0x81,0xff,0x02);_delay_ms(1);led_2(0xdf,0xff,0x04);_delay_ms(1);led_2(0xef,0xff,0x08);_delay_ms(1);led_2(0xf7,0xff,0x10);_delay_ms(1);led_2(0xfb,0xff,0x20);_delay_ms(1);led_2(0x81,0xff,0x40);_delay_ms(1);break;
		case 3:led_2(0xc3,0xff,0x02);_delay_ms(1);led_2(0xdf,0xff,0x7e);_delay_ms(1);led_2(0xc3,0xff,0x10);_delay_ms(1);led_2(0xc3,0xff,0x80);_delay_ms(1);break;
		case 4:led_2(0xfb,0xff,0x1e);_delay_ms(1);led_2(0xdf,0xff,0xfe);_delay_ms(1);led_2(0xc3,0xff,0x10);_delay_ms(1);break;
		case 5:led_2(0xfb,0xff,0x1e);_delay_ms(1);led_2(0xdf,0xff,0xf0);_delay_ms(1);led_2(0xc3,0xff,0x10);_delay_ms(1);led_2(0xc3,0xff,0x80);_delay_ms(1);led_2(0xc3,0xff,0x02);_delay_ms(1);break;
		case 6:led_2(0xfb,0xff,0xfe);_delay_ms(1);led_2(0xdf,0xff,0xf0);_delay_ms(1);led_2(0xc3,0xff,0x10);_delay_ms(1);led_2(0xc3,0xff,0x80);_delay_ms(1);led_2(0xc3,0xff,0x02);_delay_ms(1);break;
		case 7:led_2(0xc3,0xff,0x2);_delay_ms(1);led_2(0xdf,0xff,0xfe);_delay_ms(1);break;
		case 8:led_2(0xfb,0xff,0xfe);_delay_ms(1);led_2(0xdf,0xff,0xfe);_delay_ms(1);led_2(0xc3,0xff,0x10);_delay_ms(1);led_2(0xc3,0xff,0x80);_delay_ms(1);led_2(0xc3,0xff,0x02);_delay_ms(1);break;
	}
}
void T0_time()
{
	display(0,0,48+time_system_2/10%10);
	display(0,1,48+time_system_2%10);
	display(0,2,':');
	display(0,3,48+time_system_1/10%10);
	display(0,4,48+time_system_1%10);
};
void dirction()
{
	for (int i=6;i>3;i--)
	{
		if(!(PIND&bit[i]))
		{
			_delay_ms(20);
			if(!(PIND&bit[i]))
			{
				switch (i)
				{
					case 6:UCSRB=0x90;write(0x01,0);_delay_ms(20); break;
					case 5:UCSRB=0x00;write(0x01,0);_delay_ms(20);dis_string(1,0,close);break;
					case 4:TCCR2=0X6E;OCR2=0;write(0x01,0);_delay_ms(20);adc_new=ADCL+256*ADCH;adc_transient=((adc_new*100.0)/(1024.0))*5;adc_new=adc_transient;display(1,12,48+adc_new/100%10);display(1,13,'.');display(1,14,48+adc_new/10%10);display(1,15,'V');break;
				}
			}
		}
		while(!(PIND&bit[i]));
	}
	
}
SIGNAL(TIMER2_COMP_vect)
{
	OCR2++;
	if(OCR2==255)
	OCR2=0;
	_delay_ms(1);
}
SIGNAL(TIMER0_OVF_vect)
{
	sreg |=(1<<7);	
		if (T0_frequency==-9)
		{
			T0_frequency=0;
			time_system_1++;
			if (time_system_1==60)
			{
				time_system_1=0;
				time_system_2++;
			}
		}
		TCNT0=0;
		T0_frequency++;
		if (T0_frequency==31)
		{
			T0_frequency=-9;
			TCNT0=123;
		}
		
}
SIGNAL(USARTRXC_vect)
{
		usart[now]=UDR;
		now++;
		write(0x01,0);
		//display(0,8,*usart);
}
void begin()
{
	DDRA=0xfE;
	PORTA=0xFF;
	DDRB=0xff;
	PORTB=0xff;
	DDRD=0x8f;
	PORTD=0x00;
	PORTC=0xff;
	DDRC=0x00;
	init();
	led_2(0xff,0xff,0x00);
	ADMUX=0;
	ADCSRA=0xe7;
	SFIOR=0;
	
	UCSRA=0x00;
	UCSRC=0x86;
	UBRRL=51;
	
	
	TCCR0=0x05;
	TCNT0=0;
	TIMSK=(1<<0)|(1<<7);
	sreg|=(1<<7);
	
	
}
int main(void)
{
    /* Replace with your application code */
	begin();
	while(1)
	{
		T0_time();	
		lattice();
		dirction();
		dis_string(1,0,usart);
		if ((PIND&0x01))
		{
			_delay_ms(5);
			if ((PIND&0x01))
			{
			now=0;
			for (int i=0;i<10;i++)
			{
				usart[i]=0;
			}
			}
		}
		
	}
}


结尾

如有错误之处,请大家指正,感激不尽。
大家也可以评论留言,博主有时间就会回复大家的消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值