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

📄 sd54.c

📁 USB开发板 。CH375的与AVR (atmega32)。。。。
💻 C
📖 第 1 页 / 共 2 页
字号:
//6M时钟#include <avr/io.h>#include <avr/signal.h>#include <avr/interrupt.h>#include <inttypes.h>#include <avr/myavrbit.h>#define uchar unsigned char#define uint unsigned int#define receive_cmd PD0H#define ureceive_cmd PD0L#define spicsh PB4H#define spicsl PB4L#define nop asm("nop;") void avrreset();void lcd_file();//显示文件夹/**************************SD卡***************************************************************/void sdreset();void sdcmd(uint8_t cmd,uint32_t sector,uint8_t responses);void readsd();void writesd();uint8_t         buffer[512]={};//设置缓冲区/**************************SD卡***************************************************************//**************************FAT32**************************************************************/#define txt 0x100#define bmp 0xdf#define file 0x10#define T 0x54#define B 0x42void FATreset();void file_buffer_tran();//文件夹缓冲区传递void file_buffer();//写入文件夹缓冲区(初始)void read_DBR();void read_FAT();uint8_t         file_buffer1[21]={};uint8_t         file_buffer2[21]={};uint8_t         file_buffer3[21]={};uint8_t         file_buffer4[21]={};//设置文件夹缓冲区,后四位为起始簇,在后一位是文件类型uint32_t        strat_cluster[4]={};//起始簇uint8_t         file_type[4]={};//文件类型uint32_t		add_of_bootnum=16;//根目录扇区址计数(初始设置)//uint16_t 	    byte_per_sector=0;/*每扇区字节数0x0b*/uint8_t         sector_per_cluster=0;/*每簇扇区数0x0d*///uint16_t        reserved_sector=0;/*保留扇区数0x0e*///uint8_t         num_of_FAT=0;/*FAT数0x10*///uint32_t        hidden_sector=0;/*隐藏扇区数0x1c*///uint32_t        sectors_per_FAT=0;/*每FAT扇区数*///??uint32_t        large_sector=0;/*总扇区数0x20*/uint32_t		add_of_boot=0;/*根目录扇区址*/uint32_t 		add_of_FAT1=0;/*FAT1扇区址*/ uint32_t 		add_of_FAT2=0;/*FAT2扇区址*/ uint32_t        strat_c=0;//起始簇uint32_t        FAT_c=0;//FAT簇号uint8_t         file_t=0;//文件类型uint8_t 		mood=file;//状态标识uint8_t			bootnum=0;//目录计数uint8_t			txtnum=0;//TXT计数uint8_t			txtcnum=0;//TXT簇计数uint32_t        a,b,c,d;//无奈之举啊,谁叫我C不是很强呢??/**************************FAT32**************************************************************//**************************12864**************************************************************/#define csh  PB0H#define csl  PB0L#define sidh PB1H#define sidl PB1L#define clkh PB2H#define clkl PB2L#define lcdcmd  0xf8#define lcddate 0xfa#define word 1#define pic 2#define x1    0x80			/*行地址一*/#define x2    0x88          /*行地址二*/#define y0    0x9f          /*垂直地址*///#define cmd 2void main12864();void lcd_delay();void lcd_delay_w();void lcd_reset();void lcd_chinese();void lcd_picture();void lcd_write(uchar lcd_select,uchar lcd_date,uchar w_or_p);uchar lcd_add[4]={0x80,0x90,0x88,0x98};uint16_t  lcdnum=0;uchar lcdadd=0;/**************************12864**************************************************************//**************************keyboard***********************************************************/#define key PORTAvoid keyboard();//读取键值void keyfunction();void up();void down();void left();void right();void enter();void esc();void cursor();//光标void read_file();void read_txt();void read_bmp();uchar key_num[9]={0,0,1,0,2,0,0,0,3};uchar keynum;uint32_t txtadd;/**************************keyboard***********************************************************//**************************tmp175*************************************************************/#define strat_ack 0x08#define restrat_ack 0x10#define mt_sla_ack 0x18#define mr_sla_ack 0x40#define mt_date_ack 0x28#define mr_date_ack 0x50#define nop asm("nop;")#define next TWCR =  (1<<TWEN) | (1<<TWEA)//1<<TWEAvoid i2c_strat();//主机发出stratvoid i2c_restrat();//主机发出restratvoid i2c_sla_w(uchar sla_w);//主机发出add_wvoid i2c_sla_r(uchar sla_r);//主机发出add_rvoid i2c_wdate(uchar date);//主机发出datevoid i2c_rdate();//主机接收datevoid i2c_stop();//主机发出stopvoid tmp();void tmp_lcd();void tmp175();void find_tmp();void write_buffer();//将数据写入缓冲区void write_time_buffer();//将时间数据写入缓冲区void tmp_lcd_ct();void tmp_lcd_ok();const uchar point[16]={1,1,2,2,3,4,4,5,5,6,7,7,8,8,9,9};uchar tmp0[8]={0,0,0x2e,0,0xa1,0xe6,0x20,0x20};uchar tmplcdct[16]={"     00 :00     "};const uchar tmpok[16]={"    采集结束    "};const uchar tmpset[64]={"采样时间  1 分钟采样频率  1 Hz    温度采集中...                  "};uint32_t tmpcadd=0,tmpadd=0;uchar tmpc[4]={0,0,0,0};uchar tmphh=0,tmphl=0,tmph=0,tmpl=0,tmpfind=0;uchar tmplcd=0,tmpnum=4,tmp175_able=0,tmp175num=0,tmpct=60,tmpct10=0,tmpct1=0;/**************************tmp175*************************************************************//**************************ds1302***********************************************************/#define ds_clkh PD4H#define ds_clkl PD4L#define ds_dateh PD5H#define ds_datel PD5L#define ds_able PD6H#define ds_enable PD6L#define ds_in DD5L#define ds_out DD5H#define ds_read PIND5void ds1302();void ds1302_text();void ds1302_set();//1302初始化void write_data(uchar addr,uchar data);void read_data(uchar addr);void time_set(uchar sec,uchar min,uchar hour,uchar day,uchar month,uchar year);void time_lcd();void do_time(uchar m,uchar n);uchar time_tab[64]={"当前温度      ℃    当前时间    2000年00月00日      00:00:00    "};void  ds1302_lcd();void  ds1302_lcd0();uchar timeh,timel,time_reset=0,time=0;/**************************ds1302***********************************************************//*********************************************************************************************//**************************main***************************************************************/void main(){avrreset();//avr初始化sdreset();FATreset();main12864();ds1302();lcd_file();//显示文件夹do{keyboard();}while(1);}void avrreset(){//基本设置DDRA=0XFF;DDRB=0XFF;DDRC=0XFF;DDRD=0XFF;//设置为推挽输出PORTA=0;PORTB=0;PORTC=0;PORTD=0;//全部置低//中断设置DD2L;//int0输入PD2H;//int0上拉电阻开MCUCR|=0x02;//下降沿中断GICR|=0x40;//开int0SREG|=0x80;//全局中断开//定时器1设置TCCR1B = 0x00; //关定时器1TCNT1H = 0xA4; //clk/256,精度42.7us,1s计时初值为0xa472TCNT1L = 0x73;OCR1AH = 0x5B;OCR1AL = 0x8D;OCR1BH = 0x5B;OCR1BL = 0x8D;ICR1H  = 0x5B;ICR1L  = 0x8D;TCCR1A = 0x00;TIMSK = 0x04;SREG|=0x80;//全局中断开//tmp175设置DD0H;DC0L;PC0H;DC1L;PC1H;TWBR=0x04;//spi设置DB6L;//主机输入miso设置为输入,其它为输出DB5H;//MOSI置高SPCR|=(0<<SPIE)|(1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<SPR1)|(1<<SPR0);//spi中断关闭,spi使能,高位在先,主机选择,foc/16}void lcd_file(){uchar i=0,j=0;lcd_write(lcdcmd,0x30,0);//基本指令for (j=0;j<4;){lcd_write(lcdcmd,lcd_add[j],0);//设置起始地址    for(i=0;i<16;i++)	{	if(file_buffer1[i]==0) break;	else	lcd_write(lcddate,file_buffer1[i],word);	strat_cluster[0]=(file_buffer1[16]<<24)|(file_buffer1[17]<<16)|(file_buffer1[18]<<8)|file_buffer1[19];	file_type[0]=file_buffer1[20];	}j++;lcd_write(lcdcmd,lcd_add[j],0);//设置起始地址    for(i=0;i<16;i++)	{	if(file_buffer2[i]==0) break;	else	lcd_write(lcddate,file_buffer2[i],word);	strat_cluster[1]=(file_buffer2[16]<<24)|(file_buffer2[17]<<16)|(file_buffer2[18]<<8)|file_buffer2[19];	file_type[1]=file_buffer2[20];	}j++;lcd_write(lcdcmd,lcd_add[j],0);//设置起始地址    for(i=0;i<16;i++)	{	if(file_buffer3[i]==0) break;	else	lcd_write(lcddate,file_buffer3[i],word);	strat_cluster[2]=(file_buffer3[16]<<24)|(file_buffer3[17]<<16)|(file_buffer3[18]<<8)|file_buffer3[19];	file_type[2]=file_buffer3[20];	}j++;lcd_write(lcdcmd,lcd_add[j],0);//设置起始地址    for(i=0;i<16;i++)	{	if(file_buffer4[i]==0) break;	else	lcd_write(lcddate,file_buffer4[i],word);	strat_cluster[3]=(file_buffer4[16]<<24)|(file_buffer4[17]<<16)|(file_buffer4[18]<<8)|file_buffer4[19];	file_type[3]=file_buffer4[20];	}j++;}lcd_write(lcdcmd,0x80,0);lcd_write(lcddate,0xa1,word);lcd_write(lcddate,0xef,word);//写箭头strat_c=strat_cluster[0];file_t=file_type[0];	}/**************************main***************************************************************//*********************************************************************************************//**************************SD卡***************************************************************/void sdreset(){sdcmd(0,0,1);//cmd0,sd初始化sdcmd(1,0,0);//cmd1sdcmd(16,1,0);//cmd16定义块大小1扇区/512字节}void sdcmd(uint8_t cmd,uint32_t sector,uint8_t responses){sector=sector<<9;//将字节转化成扇区do{SPDR=0x40|cmd;//发送数据写入指令while(!(SPSR & (1<<SPIF)));//等待发送完毕SPDR=sector>>24;//发送数据写入  while(!(SPSR & (1<<SPIF)));//等待发送完毕 SPDR=sector>>16;//发送数据写入  while(!(SPSR & (1<<SPIF)));//等待发送完毕 SPDR=sector>>8;//发送数据写入  while(!(SPSR & (1<<SPIF)));//等待发送完毕 SPDR=sector;//发送数据写入  while(!(SPSR & (1<<SPIF)));//等待发送完毕 SPDR=0x95;//CRC,结束位while(!(SPSR & (1<<SPIF)));//等待发送完毕SPDR=0xff;//空位while(!(SPSR & (1<<SPIF)));//等待发送完毕SPDR=0xff;//空位while(!(SPSR & (1<<SPIF)));//等待发送完毕}while(SPDR!=responses);receive_cmd;//判断响应}void readsd(){uint num=0,date=0;do{SPDR=0xff;//空位while(!(SPSR & (1<<SPIF)));//等待发送完毕}while(SPDR!=0xfe);//等待起始标志for(;num<512;num++)//读数据{SPDR=0xff;//空位while(!(SPSR & (1<<SPIF)));//等待发送完毕buffer[date]=SPDR;date++;}/*SPDR=0xff;//空位while(!(SPSR & (1<<SPIF)));//等待发送完毕SPDR=0xff;//空位while(!(SPSR & (1<<SPIF)));//等待发送完毕receive_cmd;//判断响应*/sdcmd(12,0,0);}void writesd(){uint16_t num=0,date=0;SPDR=0xfe;//发送起始标志while(!(SPSR & (1<<SPIF)));//等待发送完毕for(;num<512;num++)//写数据{SPDR=buffer[date];//发送数据while(!(SPSR & (1<<SPIF)));//等待发送完毕date++;}SPDR=0xff;//空位while(!(SPSR & (1<<SPIF)));//等待发送完毕SPDR=0xff;//空位while(!(SPSR & (1<<SPIF)));//等待发送完毕do{SPDR=0xff;//空位while(!(SPSR & (1<<SPIF)));//等待发送完毕}while(SPDR&0x0f!=0x05);//等待数据确认receive_cmd;//判断响应}/**************************SD卡***************************************************************//*********************************************************************************************//**************************FAT32**************************************************************/void FATreset(){read_DBR();file_buffer();//写入文件夹缓冲区}void read_DBR(){sdcmd(18,0,0);//读块readsd();//数据读取uint16_t byte_per_sector/*每扇区字节数0x0b*/=buffer[0x0b]|(buffer[0x0c]<<8);sector_per_cluster/*每簇扇区数0x0d*/=buffer[0x0d];uint16_t reserved_sector/*保留扇区数0x0e*/=buffer[0x0e]|(buffer[0x0f]<<8);uint8_t num_of_FAT/*FAT数0x10*/=buffer[0x10];uint32_t hidden_sector/*隐藏扇区数0x1c*/=buffer[0x1c]|(buffer[0x1d]<<8)|(buffer[0x1e]<<16)|(buffer[0x1f]<<24);//large_sector/*总扇区数0x20*/=buffer[0x20]|(buffer[0x21]<<8)|(buffer[0x22]<<16)|(buffer[0x23]<<24);uint32_t sectors_per_FAT/*每FAT扇区数*/=buffer[0x24]|(buffer[0x25]<<8)|(buffer[0x26]<<16)|(buffer[0x27]<<24);add_of_boot/*根目录扇区址*/=hidden_sector/*隐藏扇区数0x1c*/+reserved_sector/*保留扇区数0x0e*/+sectors_per_FAT/*每FAT扇区数*/*num_of_FAT/*FAT数0x10*/;add_of_FAT1/*FAT1扇区址*/=reserved_sector/*保留扇区数0x0e*/+hidden_sector/*隐藏扇区数0x1c*/;add_of_FAT2/*FAT2扇区址*/=reserved_sector/*保留扇区数0x0e*/+hidden_sector/*隐藏扇区数0x1c*/+sectors_per_FAT/*每FAT扇区数*/;receive_cmd;}void file_buffer(){uchar extension1,extension2,extension3,i=0,j=0,m=0;for(i=0;i<4;)       {	   if(mood==0)read_FAT();	   if(FAT_c==0x0ffffff8&&bootnum==4)break;	   if(add_of_bootnum==16)	   {	   add_of_bootnum=0;	   if(bootnum==4)	   {	   bootnum=0;	   sdcmd(18,add_of_boot+FAT_c*8,0);//读根目录扇区址       readsd();	   }	   else	   {	   sdcmd(18,add_of_boot+FAT_c*8+bootnum,0);//读根目录扇区址       readsd();	   bootnum++;	   }	   }	   if(buffer[add_of_bootnum<<5]==0xe5||buffer[add_of_bootnum<<5]==0x2e)add_of_bootnum++;	   else	   {	   extension1=buffer[8+(add_of_bootnum<<5)];	   extension2=buffer[9+(add_of_bootnum<<5)];	   extension3=buffer[10+(add_of_bootnum<<5)];//扩展名	   if((extension1==0x54&&extension2==0x58&&extension3==0x54)||(extension1==0x42&&extension2==0x4d&&extension3==0x50)||buffer[11+(add_of_bootnum<<5)]==0x10)	   {	   file_buffer_tran();	   file_buffer1[0]=0x20;	   file_buffer1[1]=0x20;	   for(m=0;m<8;m++)file_buffer1[2+m]=buffer[m+(add_of_bootnum<<5)];	   file_buffer1[10]=0x2e;	   for(m=0;m<3;m++)file_buffer1[11+m]=buffer[8+m+(add_of_bootnum<<5)];	   file_buffer1[14]=0x20;	   file_buffer1[15]=0x20;	   file_buffer1[16]=buffer[21+(add_of_bootnum<<5)];	   file_buffer1[17]=buffer[20+(add_of_bootnum<<5)];	   file_buffer1[18]=buffer[27+(add_of_bootnum<<5)];//起始簇	   file_buffer1[19]=buffer[26+(add_of_bootnum<<5)];//起始簇	   if(buffer[11+(add_of_bootnum<<5)]==0x10)file_buffer1[20]=file;	   if(buffer[8+(add_of_bootnum<<5)]==0x54)file_buffer1[20]=T;	   if(buffer[8+(add_of_bootnum<<5)]==0x42)file_buffer1[20]=B; 	   add_of_bootnum++;	   i++;	   }else add_of_bootnum++;	   };	   };}void file_buffer_tran(){uchar m;for(m=0;m<21;m++)		{		file_buffer4[m]=file_buffer3[m];		file_buffer3[m]=0;		file_buffer3[m]=file_buffer2[m];		file_buffer2[m]=0;		file_buffer2[m]=file_buffer1[m];		file_buffer1[m]=0;		}}void read_FAT(){if(FAT_c!=0x0ffffffd){uint32_t a1,b1,c1,d1;sdcmd(18,add_of_FAT1+(strat_c>>7),0);//读块readsd();//数据读取*/a1=buffer[(FAT_c+2)<<2];b1=buffer[((FAT_c+2)<<2)+1];c1=buffer[((FAT_c+2)<<2)+2];d1=buffer[((FAT_c+2)<<2)+3];a=a1;b=b1<<8;c=c1<<16;d=d1<<24;FAT_c=(a|b|c|d)-2;}}/**************************FAT32**************************************************************//*********************************************************************************************//**************************12864**************************************************************/void lcd_delay()            //延时函数{uint i=0;for (i=0;i<2500;i++);}  void lcd_delay_w(){uint i=0;for (i=0;i<500;i++);}void main12864(){PORTA=0xe0;//置高lcd_reset();//lcd初始化}void lcd_reset(){lcd_write(lcdcmd,0x30,0);//基本指令lcd_write(lcdcmd,0x01,0);//清屏,地址指针指向00Hlcd_write(lcdcmd,0x06,0);//光标的移动方向lcd_write(lcdcmd,0x0c,0);//开显示,关游标}void lcd_write(uchar lcd_select,uchar lcd_date,uchar w_or_p)   {    uchar i,j,delay;	if(lcd_select==lcdcmd)delay=0;	else if(w_or_p==word)delay=1;	else delay=2;    csh;	for(i=0;i<8;i++)	 {	  clkl;	  if(lcd_select&0x80) {sidh;}            else  {sidl;}	  if(delay==0)lcd_delay();	  else if(delay==1)lcd_delay_w();	  clkh;	  lcd_select<<=1;					 }	for(j=0;j<2;j++)	 {	 for(i=0;i<4;i++)	  {	   clkl;	   if(lcd_date&0x80) {sidh;}             else  {sidl;}	 if(delay==0)lcd_delay();	  else if(delay==1)lcd_delay_w();	  clkh;		        lcd_date<<=1;		  } 	 for(i=0;i<4;i++) 	  {	   clkl;	   sidl;	  if(delay==0)lcd_delay();	  else if(delay==1)lcd_delay_w();	  clkh;	  }	 }   	csl; 	clkl;    }  /**************************12864**************************************************************//*********************************************************************************************//**************************keyboard***********************************************************/void key_delay()            //延时函数{uint i=0;for (i=0;i<5000;i++);}void keyboard()//判断键值{DDRA=0Xf0;key=0x0f;}SIGNAL(SIG_INTERRUPT0){ureceive_cmd;uchar x,y;GICR&=~0x40;//关int0x=(~PINA)&0x0f;DDRA=0x0f;key=0xf0;nop;nop;nop;nop;nop;nop;y=~(PINA>>4|0xf0);keynum=key_num[y]+(key_num[x]<<2);while(PINA!=0xf0);keyfunction();GICR|=0x40;//开int0}void keyfunction(){if(keynum==0x0a) up();if(keynum==0x0e) down();if(keynum==0x0d) esc();if(keynum==0x0f) right();if(keynum==0x0b) enter();if(keynum==0x0c) tmp();if(keynum==0x09) ds1302();

⌨️ 快捷键说明

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