/*************************************************
mcu:主机atmega169
使用模块:SPI通讯,AD转换查询模式
*************************************************/
#include <iom169v.h>
#include <macros.h>
#define SET_RS PORTD|=0x01
#define SET_RW PORTD|=0x02
#define SET_EN PORTD|=0x04
#define CLR_RS PORTD&=0x01
#define CLR_RW PORTD&=0x02
#define CLR_EN PORTD&=0x04
#define MAX_AD 4940
#define MIN_AD 4905
#define LCD_DATA PORTE
/*****12864地址矩阵*****/
unsigned char addr_tab[32]={
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
};
/*****毫秒延时函数*****/
void delay_ms(unsigned int t)
{
unsigned int i;
while(t--)
{
for(i=0;i<125;i++);
}
}
void delay_us(unsigned char n)
{
if (n == 0)
{
return ;
}
while (--n);
}
/*****LCD写命令函数*****/
void Lcd_WriteCmd(unsigned char cmdcode)
{
LCD_DATA = cmdcode;
CLR_RS;
CLR_RW;
SET_EN;
delay_us(5);
CLR_EN;
}
/*****LCD写数据函数*****/
void Lcd_WriteData(unsigned char dispdata)
{
LCD_DATA = dispdata;
SET_RS;
CLR_RW;
SET_EN;
delay_us(5);
CLR_EN;
}
/*****LCD初始化函数*****/
void LCD_init()
{
delay_ms(50);
Lcd_WriteCmd(0x34);
delay_ms(10);
Lcd_WriteCmd(0x30);
delay_ms(1);
Lcd_WriteCmd(0x0C);
delay_ms(1);
Lcd_WriteCmd(0x01);
delay_ms(20);
}
/*****LCD写字符串函数*****/
void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s)
{
Lcd_WriteCmd(addr_tab[8*x+y]);
while(*s>0)
{
Lcd_WriteData(*s);
s++;
}
}
/*******LCD写连续两个字符函数*************/
void LCD_write_num(unsigned char x,unsigned char y,unsigned char num1,unsigned char num2)
{
Lcd_WriteCmd(addr_tab[8*x+y]);
Lcd_WriteData(num1);
Lcd_WriteData(num2);
}
/********LCD写单个字符函数****************/
void LCD_write_char(unsigned char x,unsigned char y,unsigned char data)
{
Lcd_WriteCmd(addr_tab[8*x+y]);
Lcd_WriteData(data);
}
/********AD模块初始化函数**************************/
void ADC_init(unsigned char td,unsigned char xt)
{
PORTA= xt;
ADMUX = td; //选择AVCC,结果右对齐,选择ADC通道0
ADCSRA = 0x86; //ADC模块使能,未开始转换,自动触发关闭,中断关闭,预分频比16
ADCSRB = 0x00;
DIDR0=0xFF;
}
/********AD模块转化函数*******************************/
void ADC_convert()
{
unsigned char i;
for(i=0;i<=1;i++)
{
ADCSRA |= 1<<ADSC;
while(!(ADCSRA&(1<<ADIF))); //查询方式等待转换完成
ADCSRA &= ~(1 << ADIF);
}
ADCSRA &= ~(1 << ADEN);
}
/********端口初始化函数**************************/
void PORT_init()
{DDRA=0xFF;
PORTA=0x00;
DDRC=0xFF;
PORTC=0xFF;
DDRB=0xF7; //11110111
PORTB=0xFF;
DDRE=0xFF;
DDRF=0x00;
PORTF=0x00;
DDRD=0xFF;
PORTD=0xFF;
}
/*********SPI初始化为主机函数*************/
void SPI_MasterInit()
{
DDRB |= (1<<PB1) | (1<<PB2); /* 设置MOSI 和SCK 为输出,其他为输入 */
SPCR = (1<<SPE) | (1<<MSTR)
| (1<<SPR1) | (1<<SPR0); /* 使能SPI主机模式,设置时钟速率为fck/128 */
}
/*********1#从机SPI发送接收数据函数*****************/
unsigned char SPI_masterout(unsigned char xt)
{
PORTB &= ~(1 <<PORTB4); //强制从机模式
SPDR = xt; /* 启动数据传输 */
while (!(SPSR & (1<<SPIF)));
PORTB |= (1 <<PORTB4); //解除从机模式
SPCR |= (1<<MSTR); // MSTR有时会被清零,这里强制进入主机模式
return SPDR;
}
/*********2#从机SPI发送接收数据函数***************************/
unsigned char SPI_masterout2(unsigned char xt)
{
PORTB &= ~(1 <<PORTB5); //强制从机模式
SPDR = xt; /* 启动数据传输 */
while (!(SPSR & (1<<SPIF)));
PORTB |= (1 <<PORTB5); //解除从机模式
SPCR |= (1<<MSTR); // MSTR有时会被清零,这里强制进入主机模式
return SPDR;
}
/*********主函数******************/
void main(void)
{
unsigned char tdzj[8]={0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
unsigned char xtzj[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char td[8]={0x60,0x62,0x64,0x66,0x70,0x72,0x74,0x76};
unsigned char xt[8]={0x61,0x63,0x65,0x67,0x71,0x73,0x75,0x77};
unsigned char i;
unsigned long int adc;
unsigned char spireceive;
unsigned char by_disp_seg[4];
unsigned char hang[8]={0,0,1,1,2,2,3,3};
unsigned char lie1[8]={2,6,2,6,2,6,2,6};
unsigned char lie2[8]={3,7,3,7,3,7,3,7};
unsigned char adczj[8]={0,0,0,0,0,0,0,0};
unsigned char adcc1[8]={0,0,0,0,0,0,0,0};
unsigned char adcc2[8]={0,0,0,0,0,0,0,0};
PORT_init();
SPI_MasterInit();
LCD_init();
delay_ms(20);
LCD_init();
LCD_write_str(0,0,"请开始测试");
LCD_write_str(1,1,"按下start 键");
LCD_write_str(2,0,"");
LCD_write_str(3,3,"");
delay_ms(2000);
while(1)
{
LCD_init();
LCD_write_str(0,0," c1: . c2: . ");
LCD_write_str(1,0," c3: . c4: . ");
LCD_write_str(2,0," c5: . c6: . ");
LCD_write_str(3,0," c7: . c8: . ");
for(i=0;i<=7;i++)
{
ADC_init(tdzj[i],xtzj[i]);
delay_ms(50);
ADC_convert();
adc=ADC;
adc*=5000;
adc/=1023;
if(adc>=MAX_AD||adc<=MIN_AD)
{
adczj[i]=1;
}
by_disp_seg[0]=adc%10+0x30;
adc/=10;
by_disp_seg[1]=adc%10+0x30;
adc/=10;
by_disp_seg[2]=adc%10+0x30;
adc/=10;
by_disp_seg[3]=adc%10+0x30;
LCD_write_char(hang[i],lie1[i],by_disp_seg[3]);
LCD_write_num(hang[i],lie2[i],by_disp_seg[2],by_disp_seg[1]);
}
PORTA=0x00;
delay_ms(200);
LCD_init();
LCD_write_str(0,0," c9: . c10: . ");
LCD_write_str(1,0,"c11: . c12: . ");
LCD_write_str(2,0,"c13: . c14: . ");
LCD_write_str(3,0,"c15: . c16: . ");
spireceive=SPI_masterout(0x10);
spireceive=SPI_masterout(0x10);
for(i=0;i<=7;i++)
{
spireceive=SPI_masterout(td[i]);
LCD_write_char(hang[i],lie1[i],spireceive);
adc=spireceive;
adc=adc<<8;
delay_ms(25);
spireceive=SPI_masterout(xt[i]);
adc+=spireceive;
adc*=5000;
adc/=1023;
if(adc>=MAX_AD||adc<=MIN_AD)
{
adcc1[i]=1;
}
by_disp_seg[0]=adc%10+0x30;
adc/=10;
by_disp_seg[1]=adc%10+0x30;
adc/=10;
by_disp_seg[2]=adc%10+0x30;
adc/=10;
by_disp_seg[3]=adc%10+0x30;
LCD_write_char(hang[i],lie1[i],by_disp_seg[3]);
LCD_write_num(hang[i],lie2[i],by_disp_seg[2],by_disp_seg[1]);
delay_ms(25);
}
delay_ms(800);
LCD_init();
LCD_write_str(0,0,"c17: . c18: . ");
LCD_write_str(1,0,"c19: . c20: . ");
LCD_write_str(2,0,"c21: . c22: . ");
LCD_write_str(3,0,"c23: . c24: . ");
spireceive=SPI_masterout2(0x20);
spireceive=SPI_masterout2(0x20);
for(i=0;i<=7;i++)
{
spireceive=SPI_masterout2(td[i]);
LCD_write_char(hang[i],lie1[i],spireceive);
adc=spireceive;
adc=adc<<8;
delay_ms(25);
spireceive=SPI_masterout2(xt[i]);
adc+=spireceive;
adc*=5000;
adc/=1023;
if(adc>=MAX_AD||adc<=MIN_AD)
{
adcc2[i]=1;
}
by_disp_seg[0]=adc%10+0x30;
adc/=10;
by_disp_seg[1]=adc%10+0x30;
adc/=10;
by_disp_seg[2]=adc%10+0x30;
adc/=10;
by_disp_seg[3]=adc%10+0x30;
LCD_write_char(hang[i],lie1[i],by_disp_seg[3]);
LCD_write_num(hang[i],lie2[i],by_disp_seg[2],by_disp_seg[1]);
delay_ms(25);
}
delay_ms(800);
LCD_init();
LCD_write_str(0,0,"不合格的是:");
for(i=0;i<=7;i++)
{
if(adczj[i]>=1)
{LCD_write_char(1,i,0x31+i);
adczj[i]=0;}
else
{}
}
if(adcc1[0]>=1)
{
LCD_write_char(2,0,0x39);
adcc1[0]=0;
}
else
{}
for(i=1;i<=7;i++)
{
if(adcc1[i]>=1)
{LCD_write_num(2,i,0x31,0x2F+i);
adcc1[i]=0;
}
else
{}
}
for(i=0;i<=2;i++)
{
if(adcc2[i]>=1)
{LCD_write_num(3,i,0x31,0x37+i);
adcc2[i]=0;}
else
{}
}
for(i=3;i<=7;i++)
{
if(adcc2[i]>=1)
{
LCD_write_num(3,i,0x32,0x2D+i);
adcc2[i]=0;
}
else
{}
}
delay_ms(2000);
}
}
/******************************************
mcu:atmega8
使用模块:SPI从机中断方式,AD转换查询方式
******************************************/
#include <iom8v.h>
#include <macros.h>
void delay_us(unsigned char n)
{
if (n == 0)
{
return ;
}
while (--n);
}
/*********毫秒延时函数***************/
void delay_ms(int time)
{
int i;
for(;time>0;time--)
for(i=0;i<1000;i++);
}
/**********AD初始化函数********************/
void ADC_init(unsigned char td)
{
ADMUX = td; //选择AVCC,结果右对齐,选择ADC通道0
ADCSRA = 0x86; //ADC模块使能,未开始转换,自动触发关闭,中断关闭,预分频比16
}
/***********AD转换函数查询方式*********************/
void ADC_convert()
{
unsigned char i;
for(i=0;i<=2;i++)
{
ADCSRA |= 1<<ADSC;
while(!(ADCSRA&(1<<ADIF))); //查询方式等待转换完成
ADCSRA &= ~(1 << ADIF);
}
ADCSRA &= ~(1 << ADEN);
}
/************端口初始化函数*******************/
void PORT_init()
{
DDRD=0xFF;
PORTD=0x00;
DDRC=0x00;
PORTC=0x00;
DDRB=0xEB;
PORTB=0x00;
}
/*************SPI初始化为从机***********************/
void SPI_SlaveInit(void)
{
/* 设置MISO 为输出,其他为输入 */
DDRB |= (1<<PB4);
SPCR =0xC0; //使能SPI
SPSR=0x00;
}
void main()
{
CLI();
PORT_init();
SPI_SlaveInit();
MCUCR=0x00;
GICR=0x00;
TIMSK=0x00;
PORTD=0x80;
ADC_init(0x47);
ADC_convert();
PORTD=0x00;
SEI();
while(1)
{
}
}
#pragma interrupt_handler SPI_stc_isr: iv_SPI_STC
void SPI_stc_isr()
{
unsigned int adc;
unsigned char adcl;
unsigned char adch;
switch(SPDR)
{
case 0x10:
SPDR=0x11;
while (!(SPSR & (1<<SPIF)));
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adch;
PORTD=0x40;
break;
case 0x60:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adcl;
ADC_init(0x46);
ADC_convert();
break;
case 0x61:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adch;
PORTD=0x20;
break;
case 0x62:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adcl;
ADC_init(0x45);
ADC_convert();
break;
case 0x63:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adch;
PORTD=0x10;
break;
case 0x64:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adcl;
ADC_init(0x44);
ADC_convert();
break;
case 0x65:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adch;
PORTD=0x08;
break;
case 0x66:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adcl;
ADC_init(0x43);
ADC_convert();
break;
case 0x67:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adch;
PORTD=0x04;
break;
case 0x70:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adcl;
ADC_init(0x42);
ADC_convert();
break;
case 0x71:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adch;
PORTD=0x02;
break;
case 0x72:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adcl;
ADC_init(0x41);
ADC_convert();
break;
case 0x73:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adch;
PORTD=0x01;
break;
case 0x74:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adcl;
ADC_init(0x40);
ADC_convert();
break;
case 0x75:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adch;
PORTD=0x80;
break;
case 0x76:
adc=ADC;
adcl=adc;
adc=adc>>8;
adch=adc;
SPDR=adcl;
ADC_init(0x47);
ADC_convert();
break;
case 0x77:
SPDR=0x10;
PORTD=0x00;
break;
default:
break;
}
} |