📄 testlcd.lst
字号:
(0145) //VS1003软件复位 //VS1003 soft reset
(0146) void VS1011B_SoftReset(void)
(0147) {
(0148) VS1011B_WriteCMD(0x00,0x0804);//写复位 //reset
_VS1011B_SoftReset:
65D E024 LDI R18,4
65E E038 LDI R19,0x8
65F 2700 CLR R16
660 DF46 RCALL _VS1011B_WriteCMD
(0149) Delay(2);//延时,至少1.35ms //wait at least 1.35ms
661 E002 LDI R16,2
662 E010 LDI R17,0
663 D40D RCALL _Delay
(0150) DDRA &=~BIT(VS1011B_DREQ); //DREQ为输入
664 98D2 CBI 0x1A,2
(0151) PORTA|= BIT(VS1011B_DREQ); //DREQ=1
665 9ADA SBI 0x1B,2
666 9508 RET
FILE: D:\学习\AVRpro\Mega16程序\TestLCD\ADC.C
(0001) //*********************************************
(0002) //ADC转换
(0003) //MCU:AVR_MEGA16L ,晶振频率:8.0 MHz
(0004) //ADC通道:ADC3,PA3,采用软件方式
(0005) //制作人:平顶山工学院计算机系,郭猛
(0006) //**********************************************
(0007)
(0008) #include "iom16v.h"
(0009) #include "macros.h"
(0010) #include "LCDFun.h"
(0011) #include "VS1011B.h"
(0012) #include "mmc.h"
(0013)
(0014) #define Vref 330 //参考电压为3.3V
(0015) #define VolMax 651 //电池电量满,4.2V/2=2.1,对应ADC结果为0x3ff*(2.1/3.3)=651
(0016) #define VolMin 520 //电池电量空,3.3V/2=1.65V,对应ADC结果为0x3ff*(1.65/3.3)=512
(0017) #define ADC_MUX 0x03 //ADC通道(注意将下面的ADC_MUX改为3)
(0018)
(0019) extern void DisplayLong(unsigned long ll,unsigned char line);
(0020)
(0021) void MCUMode(uchar iMode) //设置CPU的休眠模式
(0022) {
(0023) //关闭看门狗:
(0024) WDTCR=BIT(WDTOE)|BIT(WDE);
_MCUMode:
iMode --> R16
667 E188 LDI R24,0x18
668 BD81 OUT 0x21,R24
(0025) WDTCR=0;
669 2422 CLR R2
66A BC21 OUT 0x21,R2
(0026) if (iMode<=6)
66B E086 LDI R24,6
66C 1780 CP R24,R16
66D F048 BCS 0x0677
(0027) {
(0028) //设置CPU的休眠模式
(0029) MCUCR|=(iMode&0x70);
66E 2F80 MOV R24,R16
66F 7780 ANDI R24,0x70
670 B625 IN R2,0x35
671 2A28 OR R2,R24
672 BE25 OUT 0x35,R2
(0030) //CPU的休眠
(0031) MCUCR|=BIT(SE);
673 B785 IN R24,0x35
674 6480 ORI R24,0x40
675 BF85 OUT 0x35,R24
(0032) asm("sleep");
676 9588 SLEEP
(0033) ;;
(0034) }
677 9508 RET
(0035) }
(0036)
(0037) //ADC初始化函数
(0038) void ADC_Init(void)
(0039) {
(0040) DDRA&=~BIT(3); //端口A设置为高阻态
_ADC_Init:
678 98D3 CBI 0x1A,3
(0041) PORTA&=~BIT(3);
679 98DB CBI 0x1B,3
(0042)
(0043) ADCSRA=0x00;
67A 2422 CLR R2
67B B826 OUT 0x06,R2
(0044) ADMUX=BIT(REFS0)|(3&0x0f); //选择内部AVcc为基准,ADC数据左对齐
67C E483 LDI R24,0x43
67D B987 OUT 0x07,R24
(0045) ACSR=BIT(ACD); //关闭模拟比较器
67E E880 LDI R24,0x80
67F B988 OUT 0x08,R24
(0046) ADCSRA=BIT(ADEN)|BIT(ADPS2)|BIT(ADPS1); //CLK64分频,不产生ADC中断
680 E886 LDI R24,0x86
681 B986 OUT 0x06,R24
682 9508 RET
_ADC_Convert:
i --> Y,+1
rslt --> R20
adc_reslt --> R22
683 940E 16A7 CALL push_xgsetF000
(0047) }
(0048)
(0049) //ADC转换处理函数:
(0050) unsigned char ADC_Convert(void)
(0051) {
(0052) unsigned int adc_reslt=0; //AD转换结果
685 2766 CLR R22
686 2777 CLR R23
(0053) unsigned char rslt,i;
(0054) ADCSRA|=BIT(ADSC); //启动AD转换
687 9A36 SBI 0x06,6
(0055) while(!(ADCSRA & BIT(ADIF))) ; //等待AD转换完毕
688 9B34 SBIS 0x06,4
689 CFFE RJMP 0x0688
(0056) adc_reslt=ADC&0x03FF; //保存ADC结果
68A B164 IN R22,0x04
68B B175 IN R23,0x05
68C 7073 ANDI R23,3
(0057) //测试使用,显示adc_reslt:
(0058) //DisplayLong(adc_reslt,5);
(0059) //Delay(500);
(0060) //对ADC结果进行处理
(0061) if (adc_reslt<=VolMin) //电量为空/不足
68D E088 LDI R24,0x8
68E E092 LDI R25,2
68F 1786 CP R24,R22
690 0797 CPC R25,R23
691 F010 BCS 0x0694
(0062) rslt=0;
692 2744 CLR R20
693 C012 RJMP 0x06A6
(0063) else if (adc_reslt>=VolMax) //电量为满
694 386B CPI R22,0x8B
695 E0E2 LDI R30,2
696 077E CPC R23,R30
697 F010 BCS 0x069A
(0064) rslt=14;
698 E04E LDI R20,0xE
699 C00C RJMP 0x06A6
(0065) else //[其它介于0~13的情况]
(0066) rslt=(((adc_reslt-VolMin)*14)/(VolMax-VolMin));
69A 019B MOVW R18,R22
69B 5028 SUBI R18,0x8
69C 4032 SBCI R19,2
69D E00E LDI R16,0xE
69E E010 LDI R17,0
69F 940E 1650 CALL empy16s
6A1 E823 LDI R18,0x83
6A2 E030 LDI R19,0
6A3 940E 15C0 CALL div16u
6A5 2F40 MOV R20,R16
(0067) ADCSRA|=BIT(ADIF); //ADIF位写入1,清零
6A6 9A34 SBI 0x06,4
(0068) ADCSRA&=~BIT(ADEN); //禁止ADC
6A7 9837 CBI 0x06,7
(0069) return rslt;
6A8 2F04 MOV R16,R20
6A9 940C 16AA JMP pop_xgsetF000
_E2PROM_Write:
i --> R10
Cnt --> Y,+1
Data --> R18
IAddress --> R16
6AB 92AA ST R10,-Y
FILE: D:\学习\AVRpro\Mega16程序\TestLCD\E2PROM.C
(0001) //******************************************************************************
(0002) //MCU:ATMEL AVR MEGA16L ,晶振频率:8MHz,频率越高,播放Mp3越流畅
(0003) //用到硬件器件: MEGA16L内部的512B EEPROM
(0004) //EEPROM用来保存基本的参数,如:
(0005) //音量(0)、重低音(1)、当前歌曲(2,3)、遥控模式(4)
(0006) //RECS80遥控按键(5-8,9-12,13-16,17-20).
(0007) //RC5遥控按键(21-24,25-28,29-32,33-36).
(0008) //制作人:平顶山工学院计算机系,郭猛
(0009) //******************************************************************************
(0010) # include "iom16v.h"
(0011) # include "macros.h"
(0012)
(0013) //在E2PROM写入指定长度的数据
(0014) //IAddress:起始地址,*Data:要写入的数据首地址,Cnt:要写入的数据个数
(0015) //函数无返回值
(0016) void E2PROM_Write(unsigned int IAddress,unsigned char *Data,unsigned char Cnt)
(0017) {
(0018) unsigned char i;
(0019) CLI(); //程序进入临界区
6AC 94F8 BCLR 7
(0020) for(i=0;i<Cnt;i++)
6AD 24AA CLR R10
6AE C012 RJMP 0x06C1
(0021) {
(0022) //等待前一次写操作完毕
(0023) while(EECR & BIT(EEWE)) ;
6AF 99E1 SBIC 0x1C,1
6B0 CFFE RJMP 0x06AF
(0024) EEAR = IAddress + i;
6B1 2C2A MOV R2,R10
6B2 2433 CLR R3
6B3 0128 MOVW R4,R16
6B4 0C42 ADD R4,R2
6B5 1C53 ADC R5,R3
6B6 BA5F OUT 0x1F,R5
6B7 BA4E OUT 0x1E,R4
(0025) EEDR = Data[i];
6B8 2DE2 MOV R30,R2
6B9 27FF CLR R31
6BA 0FE2 ADD R30,R18
6BB 1FF3 ADC R31,R19
6BC 8020 LDD R2,Z+0
6BD BA2D OUT 0x1D,R2
(0026) EECR|= BIT(EEMWE);
6BE 9AE2 SBI 0x1C,2
(0027) ;;;; //等待4个周期
(0028) EECR|= BIT(EEWE);
6BF 9AE1 SBI 0x1C,1
6C0 94A3 INC R10
6C1 8009 LDD R0,Y+1
6C2 14A0 CP R10,R0
6C3 F358 BCS 0x06AF
(0029) }
(0030) SEI(); //程序退出临界区
6C4 9478 BSET 7
6C5 90A9 LD R10,Y+
6C6 9508 RET
(0031) }
(0032)
(0033) //在E2PROM写入指定长度的数据
(0034) //IAddress:起始地址,*Data:要写入的数据首地址,Cnt:要写入的数据个数
(0035) //函数返回一个字节
(0036) unsigned char E2PROM_Read_OneChar(unsigned int IAddress)
(0037) {
(0038) CLI(); //程序进入临界区
_E2PROM_Read_OneChar:
IAddress --> R16
6C7 94F8 BCLR 7
(0039) //等待前一次操作完毕
(0040) while(EECR & BIT(EEWE)) ;
6C8 99E1 SBIC 0x1C,1
6C9 CFFE RJMP 0x06C8
(0041) EEAR = IAddress;
6CA BB1F OUT 0x1F,R17
6CB BB0E OUT 0x1E,R16
(0042) EECR|= BIT(EERE);
6CC 9AE0 SBI 0x1C,0
(0043) ; //等待1个周期
(0044) SEI(); //程序退出临界区
6CD 9478 BSET 7
(0045) return EEDR;
6CE B30D IN R16,0x1D
6CF 9508 RET
_fat_root_dir_addr:
VBRadd --> R12
bootp32 --> R14
bootp --> R10
buff --> R14
6D0 940E 169C CALL push_xgsetF0FC
6D2 0178 MOVW R14,R16
6D3 9722 SBIW R28,2
FILE: D:\学习\AVRpro\Mega16程序\TestLCD\fat.c
(0001) #include "fat.h"
(0002) #include "mmc.h"
(0003)
(0004) //每扇区的字节数目
(0005) unsigned int BlockSize; //每扇区的字节数,一般为512
(0006) unsigned long fat_offset; ////FAT1的起始扇区号
(0007) unsigned long data_offset; //数据区的起始扇区数,FAT32的根目录区和数据区重合:
(0008) unsigned char FatFlags; //FAT类型:FAT32,FAT16,FAT12
(0009) unsigned long blocknow;
(0010) unsigned char SecPerClus; //每个簇占用的扇区数目,1GB的SD卡应为8
(0011) unsigned char *pointer_FDT;
(0012) unsigned long FirstRootDirSecNum; //根目录区(FDT)的起始扇区号
(0013) unsigned int old_pos_a=0;
(0014) unsigned long old_pos_blk;
(0015)
(0016) const unsigned char Search_FileExName1[3]={'M','P','3'}; //要查找的是TXT文件,可以改成其它的
(0017)
(0018) //############################################################################
(0019) //从BPB中获取根目录区的起始地址,同时判断FAT制式(判定方法不可靠,不是微软推荐的)
(0020) unsigned long fat_root_dir_addr(unsigned char *buff)
(0021) //############################################################################
(0022) {
(0023) struct BootSec *bootp; //FAT16 BPB
(0024) struct BootSec32 *bootp32; //FAT32 BPB
(0025) unsigned int VBRadd; //DBR起始扇区号,在它之前都是磁盘分区信息占用的扇区数目
(0026)
(0027) MMC_SD_ReadSingleBlock(BIOS_PARAMETER_BLOCK,buff); //读取BPB/MBR
6D4 82F9 STD Y+1,R15
6D5 82E8 STD Y+0,R14
6D6 E000 LDI R16,0
6D7 E010 LDI R17,0
6D8 E020 LDI R18,0
6D9 E030 LDI R19,0
6DA 940E 14AB CALL _MMC_SD_ReadSingleBlock
(0028) if(buff[0] != 0xEB || buff[0] != 0xE9) //buff[0]!=0xEB,0xE9,this is mbr //我们的SD卡应该是这一种
6DC 01F7 MOVW R30,R14
6DD 8020 LDD R2,Z+0
6DE 2433 CLR R3
6DF 2D82 MOV R24,R2
6E0 3E8B CPI R24,0xEB
6E1 F411 BNE 0x06E4
6E2 3E89 CPI R24,0xE9
6E3 F071 BEQ 0x06F2
(0029) {
(0030) VBRadd = buff[VBR_ADDR] + (buff[VBR_ADDR + 1])*256; //real BPB address
6E4 01F7 MOVW R30,R14
6E5 53E9 SUBI R30,0x39
6E6 4FFE SBCI R31,0xFE
6E7 8120 LDD R18,Z+0
6E8 940E 19FC CALL 0x19FC
6EA 01F7 MOVW R30,R14
6EB 53EA SUBI R30,0x3A
6EC 4FFE SBCI R31,0xFE
6ED 80C0 LDD R12,Z+0
6EE 24DD CLR R13
6EF 0EC0 ADD R12,R16
6F0 1ED1 ADC R13,R17
(0031) }
6F1 C002 RJMP 0x06F4
(0032) else // buff[0]==0xEB,mbr和DBR相同,都是从0扇区开始
(0033) {
(0034) VBRadd = 0;
6F2 24CC CLR R12
6F3 24DD CLR R13
(0035) }
(0036) MMC_SD_ReadSingleBlock(VBRadd,buff); //重新再读取DBR
6F4 82F9 STD Y+1,R15
6F5 82E8 STD Y+0,R14
6F6 0186 MOVW R16,R12
6F7 0197 MOVW R18,R14
6F8 2722 CLR R18
6F9 2733 CLR R19
6FA 940E 14AB CALL _MMC_SD_ReadSingleBlock
(0037)
(0038) bootp=(struct BootSec *)buff; //Fat16 的BPB
6FC 0157 MOVW R10,R14
(0039) bootp32=(struct BootSec32 *)buff; //Fat32 的BPB
(0040)
(0041) if(bootp->BPB_RootEntCnt == 0) //根据根目录下面项目数为0,确定是FAT32
6FD 01F5 MOVW R30,R10
6FE 8821 LDD R2,Z+17
6FF 8832 LDD R3,Z+18
700 2022 TST R2
701 F009 BEQ 0x0703
702 C034 RJMP 0x0737
703 2033 TST R3
704 F009 BEQ 0x0706
705 C031 RJMP 0x0737
(0042) {
(0043) BlockSize=bootp32->BPB_BytesPerSec; //获取每扇区字节数目
706 940E 19E0 CALL 0x19E0
(0044) FatFlags = FAT_Flg_32; //Fat32文件系统
708 E082 LDI R24,2
709 9380 00C1 STS FatFlags,R24
70B 940E 184C CALL 0x184C
(0045) fat_offset = bootp32->BPB_RsvdSecCnt + VBRadd; //FAT1的起始扇区号
(0046) //根目录区(FDT)的起始扇区号=保留扇区+FAT占用扇区:
(0047) FirstRootDirSecNum=VBRadd+(bootp32->BPB_RsvdSecCnt+(bootp32->BPB_NumFATs*bootp32->BPB_FATSz32));
70D A024 LDD R2,Z+36
70E A035 LDD R3,Z+37
70F A046 LDD R4,Z+38
710 A057 LDD R5,Z+39
711 8900 LDD R16,Z+16
712 2711 CLR R17
713 2722 CLR R18
714 2733 CLR R19
715 940E 17B6 CALL 0x17B6
717 940E 1660 CALL empy32s
719 01F7 MOVW R30,R14
71A 8426 LDD R2,Z+14
71B 8437 LDD R3,Z+15
71C 2444 CLR R4
71D 2455 CLR R5
71E 0E20 ADD R2,R16
71F 1E31 ADC R3,R17
720 1E42 ADC R4,R18
721 1E53 ADC R5,R19
722 0136 MOVW R6,R12
723 2488 CLR R8
724 2499 CLR R9
725 940E 1877 CALL 0x1877
727 9270 00B7 STS FirstRootDirSecNum+1,R7
729 9260 00B6 STS FirstRootDirSecNum,R6
72B 9290 00B9 STS FirstRootDirSecNum+3,R9
72D 9280 00B8 STS FirstRootDirSecNum+2,R8
(0048) SecPerClus = bootp32->BPB_SecPerClus; //每个簇占用的扇区数目,SD卡应为8
72F 8425 LDD R2,Z+13
730 9220 00BC STS SecPerClus,R2
(0049) //数据区的起始扇区数,FAT32的根目录区和数据区重合:
(0050) data_offset = FirstRootDirSecNum;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -