📄 tcxoboard.lst
字号:
(0001) /*
(0002) T/C1使用PWM控制方式,进行DA转换。
(0003) 直接对OCR1A、OCR1B写入电压数据,两路输出,精度12位
(0004) */
(0005) #include <iom8v.h>
(0006) #include <macros.h>
(0007) #define Vref 4995
(0008) //参考电压值
(0009) //T1初始化程序
(0010) void pwm1_init(void)
(0011) {
(0012) TCCR1B = 0;
_pwm1_init:
013E 2422 CLR R2
013F BC2E OUT 0x2E,R2
(0013) //PWM停止工作
(0014) DDRB=0b00000110;
0140 E086 LDI R24,6
0141 BB87 OUT 0x17,R24
(0015) //OC1A作为PWMA输出引脚,OC1B作为PWMB输出引脚
(0016) ICR1=0x0FFF;
0142 EF8F LDI R24,0xFF
0143 E09F LDI R25,0xF
0144 BD97 OUT 0x27,R25
0145 BD86 OUT 0x26,R24
(0017) //PWM模式14,ICR1作为top值,12位精度
(0018) TCNT1=0;
0146 2433 CLR R3
0147 BC3D OUT 0x2D,R3
0148 BC2C OUT 0x2C,R2
(0019) OCR1A=0x0000;
0149 BC3B OUT 0x2B,R3
014A BC2A OUT 0x2A,R2
(0020) OCR1B=0x0000;
014B BC39 OUT 0x29,R3
014C BC28 OUT 0x28,R2
(0021) /*
(0022) 启动两路PWM输出,工作模式14(WGM XX),以系统时钟工作(CS XX)
(0023) 两路均为计数至TOP时,输出引脚清零(COM1 X1:COM1 X0),换言之,正占空比与
(0024) OCR1X成正比
(0025) */
(0026) TCCR1A =(1<<WGM11)|(1<<COM1A1)|(1<<COM1B1);
014D EA82 LDI R24,0xA2
014E BD8F OUT 0x2F,R24
(0027) TCCR1B =(1<<WGM13)|(1<<WGM12)|(1<<CS10);
014F E189 LDI R24,0x19
0150 BD8E OUT 0x2E,R24
0151 9508 RET
FILE: G:\Mega8程序\TCXO评估板\Main\ADC.c
(0001) #include <iom8v.h>
(0002) #include <macros.h>
(0003) #define Vref 4995//参考电压值
(0004) unsigned int adc_rel=0;//AD转换结果
(0005) unsigned char adc_mux=0;//AD通道,默认为0通道
(0006) void adc_init(void)//ADC初始化,并启动AD转换
(0007) {DDRC=0x00;
_adc_init:
0152 2422 CLR R2
0153 BA24 OUT 0x14,R2
(0008) PORTC=0x00;
0154 BA25 OUT 0x15,R2
(0009) ADCSRA = 0x00;
0155 B826 OUT 0x06,R2
(0010) //状态控制寄存器复位
(0011) ADMUX =(1<<REFS0)|(adc_mux&0x0f);
0156 9180008C LDS R24,adc_mux
0158 708F ANDI R24,0xF
0159 6480 ORI R24,0x40
015A B987 OUT 0x07,R24
(0012) //选择内部AVCC为基准,并选取当前转换通道(转换为0~7)
(0013) ACSR =(1<<ACD);
015B E880 LDI R24,0x80
015C B988 OUT 0x08,R24
(0014) //关闭模拟比较器(使用ADC时必须关断)
(0015) ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1) ;
015D EC8E LDI R24,0xCE
015E B986 OUT 0x06,R24
015F 9508 RET
_adc_isr:
0160 938A ST R24,-Y
0161 939A ST R25,-Y
0162 B78F IN R24,0x3F
0163 938A ST R24,-Y
(0016) //允许AD转换,启动AD转换,开启AD转换中断,64预分频
(0017) }
(0018) #pragma interrupt_handler adc_isr:iv_ADC //ADC完成中断
(0019) void adc_isr(void)
(0020) {adc_rel=ADC&0x3ff;
0164 B184 IN R24,0x04
0165 B195 IN R25,0x05
0166 7093 ANDI R25,3
0167 9390008B STS adc_rel+1,R25
0169 9380008A STS adc_rel,R24
(0021) //摒除高位数据,10位转换
(0022) ADMUX=(1<<REFS0)|(adc_mux&0x0f);
016B 9180008C LDS R24,adc_mux
016D 708F ANDI R24,0xF
016E 6480 ORI R24,0x40
016F B987 OUT 0x07,R24
(0023) //选择内部AVCC为基准,并选取当前转换通道(转换为0~7)
(0024) ADCSRA|=(1<<ADSC);
0170 9A36 SBI 0x06,6
0171 9189 LD R24,Y+
0172 BF8F OUT 0x3F,R24
0173 9199 LD R25,Y+
0174 9189 LD R24,Y+
0175 9518 RETI
FILE: G:\Mega8程序\TCXO评估板\Main\Uart.c
(0001) /*
(0002) 串口通信模块,使用之前,应该在Main 函数中对串口进行初始化,
(0003) 串口数据接收方式采用中断进行
(0004) */
(0005) #include <iom8v.h>
(0006) #include <macros.h>
(0007) #define fosc 8000000 //晶振8MHZ
(0008) #define baud 19200 //波特率
(0009) extern void adc_init(void);
(0010) extern unsigned int adc_rel;//AD转换结果
(0011) extern unsigned char adc_mux;//AD通道,默认为0通道
(0012) extern unsigned char InterruptFlag;
(0013)
(0014) extern unsigned char ExtendRomAddr,ExtendRomVal;//定义片外EEPROM
(0015) extern unsigned char ExtendRomRW;
(0016)
(0017) unsigned int eeprom_addr;
(0018) unsigned char eeprom_val;
(0019) unsigned char getchar(void) {while(!(UCSRA& (1<<RXC)));return UDR;}
_getchar:
0176 9B5F SBIS 0x0B,7
0177 CFFE RJMP _getchar
0178 B10C IN R16,0x0C
0179 9508 RET
(0020) /*字符输出函数*/
(0021) void putchar(unsigned char c)
(0022) {
(0023) while (!(UCSRA&(1<<UDRE)));
_putchar:
c --> R16
017A 9B5D SBIS 0x0B,5
017B CFFE RJMP _putchar
(0024) UDR=c;
017C B90C OUT 0x0C,R16
017D 9508 RET
_puts:
s --> R20
017E D295 RCALL push_gset1
017F 01A8 MOVW R20,R16
(0025) }
(0026)
(0027) /*字符串输出函数*/
(0028) void puts(char *s)
(0029) {
0180 C005 RJMP 0x0186
(0030) while (*s)
(0031) {
(0032) putchar(*s);
0181 01FA MOVW R30,R20
0182 8100 LDD R16,Z+0
0183 DFF6 RCALL _putchar
(0033) s++;
0184 5F4F SUBI R20,0xFF
0185 4F5F SBCI R21,0xFF
0186 01FA MOVW R30,R20
0187 8020 LDD R2,Z+0
0188 2022 TST R2
0189 F7B9 BNE 0x0181
(0034) }
(0035) putchar(13);
018A E00D LDI R16,0xD
018B DFEE RCALL _putchar
(0036) putchar(10);
018C E00A LDI R16,0xA
018D DFEC RCALL _putchar
018E D288 RCALL pop_gset1
018F 9508 RET
(0037) }
(0038)
(0039) void uart_init(void)
(0040) {
(0041) //OSCCAL=0xA1;//在主程序中设置
(0042) UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
_uart_init:
0190 E988 LDI R24,0x98
0191 B98A OUT 0x0A,R24
(0043) //允许接收中断、发送和接收
(0044) UBRRL=(fosc/16/baud-1)%256;
0192 E189 LDI R24,0x19
0193 B989 OUT 0x09,R24
(0045) UBRRH=((fosc/16/baud-1)/256)&0b01111111;
0194 2422 CLR R2
0195 BC20 OUT 0x20,R2
(0046) UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
0196 E886 LDI R24,0x86
0197 BD80 OUT 0x20,R24
0198 9508 RET
_UartGet:
channel --> R14
val --> R20
i --> R22
temp --> R10
charInput --> R12
0199 D29D RCALL push_lset
019A D299 RCALL push_gset5
(0047) //8位数据+1位STOP位
(0048) }
(0049)
(0050) #pragma interrupt_handler UartGet:12
(0051) void UartGet(void)//使用中断方式接收UART的输入字符
(0052) {
(0053) unsigned char charInput,channel='0',i;
019B E380 LDI R24,0x30
019C 2EE8 MOV R14,R24
(0054) unsigned int val=0,temp=1000;
019D 2744 CLR R20
019E 2755 CLR R21
019F EE88 LDI R24,0xE8
01A0 E093 LDI R25,3
01A1 015C MOVW R10,R24
(0055) static unsigned char LED_state=0;
(0056) charInput=UDR;
01A2 B0CC IN R12,0x0C
(0057) switch (charInput)
01A3 2D6C MOV R22,R12
01A4 2777 CLR R23
01A5 3567 CPI R22,0x57
01A6 E0E0 LDI R30,0
01A7 077E CPC R23,R30
01A8 F409 BNE 0x01AA
01A9 C09C RJMP 0x0246
01AA E587 LDI R24,0x57
01AB E090 LDI R25,0
01AC 1786 CP R24,R22
01AD 0797 CPC R25,R23
01AE F07C BLT 0x01BE
01AF 346D CPI R22,0x4D
01B0 E0E0 LDI R30,0
01B1 077E CPC R23,R30
01B2 F409 BNE 0x01B4
01B3 C046 RJMP 0x01FA
01B4 346F CPI R22,0x4F
01B5 E0E0 LDI R30,0
01B6 077E CPC R23,R30
01B7 F0B1 BEQ 0x01CE
01B8 3562 CPI R22,0x52
01B9 E0E0 LDI R30,0
01BA 077E CPC R23,R30
01BB F409 BNE 0x01BD
01BC C04B RJMP 0x0208
01BD C0FF RJMP 0x02BD
01BE 3762 CPI R22,0x72
01BF E0E0 LDI R30,0
01C0 077E CPC R23,R30
01C1 F409 BNE 0x01C3
01C2 C065 RJMP 0x0228
01C3 3762 CPI R22,0x72
01C4 E0E0 LDI R30,0
01C5 077E CPC R23,R30
01C6 F40C BGE 0x01C8
01C7 C0F5 RJMP 0x02BD
01C8 3767 CPI R22,0x77
01C9 E0E0 LDI R30,0
01CA 077E CPC R23,R30
01CB F409 BNE 0x01CD
01CC C0B6 RJMP 0x0283
01CD C0EF RJMP 0x02BD
(0058) {
(0059) case 'O'://调节输出电压'O'
(0060) {
(0061) channel=getchar();
01CE DFA7 RCALL _getchar
01CF 2EE0 MOV R14,R16
(0062) charInput=getchar();//无用的前导空格字符
01D0 DFA5 RCALL _getchar
01D1 2EC0 MOV R12,R16
(0063) for(i=0;i<4;i++)//将4位(0~4995)BCD转换为为integer
01D2 2766 CLR R22
01D3 C010 RJMP 0x01E4
(0064) {
(0065) charInput=getchar()-48;
01D4 DFA1 RCALL _getchar
01D5 2F80 MOV R24,R16
01D6 5380 SUBI R24,0x30
01D7 2EC8 MOV R12,R24
(0066) val+=charInput*temp;
01D8 2F08 MOV R16,R24
01D9 2711 CLR R17
01DA 0195 MOVW R18,R10
01DB D222 RCALL empy16s
01DC 0F40 ADD R20,R16
01DD 1F51 ADC R21,R17
(0067) temp/=10;
01DE E02A LDI R18,0xA
01DF E030 LDI R19,0
01E0 0185 MOVW R16,R10
01E1 D202 RCALL div16u
01E2 0158 MOVW R10,R16
01E3 9563 INC R22
01E4 3064 CPI R22,4
01E5 F370 BCS 0x01D4
(0068) }
(0069) if (val>0xfff) val=0xfff;
01E6 EF8F LDI R24,0xFF
01E7 E09F LDI R25,0xF
01E8 1784 CP R24,R20
01E9 0795 CPC R25,R21
01EA F410 BCC 0x01ED
01EB EF4F LDI R20,0xFF
01EC E05F LDI R21,0xF
(0070) if (channel=='0') OCR1A=val;
01ED 2D8E MOV R24,R14
01EE 3380 CPI R24,0x30
01EF F419 BNE 0x01F3
01F0 BD5B OUT 0x2B,R21
01F1 BD4A OUT 0x2A,R20
01F2 C0CA RJMP 0x02BD
(0071) else if (channel=='1') OCR1B=val;
01F3 2D8E MOV R24,R14
01F4 3381 CPI R24,0x31
01F5 F009 BEQ 0x01F7
01F6 C0C6 RJMP 0x02BD
01F7 BD59 OUT 0x29,R21
01F8 BD48 OUT 0x28,R20
(0072) break;
01F9 C0C3 RJMP 0x02BD
(0073) }
(0074) case 'M'://读取ADC通道及ADC转换结果
(0075) {
(0076) channel=getchar();
01FA DF7B RCALL _getchar
01FB 2EE0 MOV R14,R16
(0077) adc_mux=channel-48;//将ASCII码转换为数字
01FC 2D8E MOV R24,R14
01FD 5380 SUBI R24,0x30
01FE 9380008C STS adc_mux,R24
(0078) TCNT0=0x10;//防止串口接受信息时,Timer0中断即将发生。
0200 E180 LDI R24,0x10
0201 BF82 OUT 0x32,R24
(0079) InterruptFlag|=0b00000001;//通知Timer0中断程序,需要发送测试数据
0202 91800089 LDS R24,InterruptFlag
0204 6081 ORI R24,1
0205 93800089 STS InterruptFlag,R24
(0080) break;
0207 C0B5 RJMP 0x02BD
(0081) }
(0082)
(0083) case 'R'://读取片内EEPROM
(0084) {
(0085) charInput=getchar();//无用的前导空格字符
0208 DF6D RCALL _getchar
0209 2EC0 MOV R12,R16
(0086) for(i=0;i<4;i++)//将4位(0~4995)BCD转换为为integer
020A 2766 CLR R22
020B C010 RJMP 0x021C
(0087) {
(0088) charInput=getchar()-48;
020C DF69 RCALL _getchar
020D 2F80 MOV R24,R16
020E 5380 SUBI R24,0x30
020F 2EC8 MOV R12,R24
(0089) val+=charInput*temp;
0210 2F08 MOV R16,R24
0211 2711 CLR R17
0212 0195 MOVW R18,R10
0213 D1EA RCALL empy16s
0214 0F40 ADD R20,R16
0215 1F51 ADC R21,R17
(0090) temp/=10;
0216 E02A LDI R18,0xA
0217 E030 LDI R19,0
0218 0185 MOVW R16,R10
0219 D1CA RCALL div16u
021A 0158 MOVW R10,R16
021B 9563 INC R22
021C 3064 CPI R22,4
021D F370 BCS 0x020C
(0091) }
(0092) eeprom_addr=val;
021E 93500092 STS eeprom_addr+1,R21
0220 93400091 STS eeprom_addr,R20
(0093) InterruptFlag|=0b00000010;//通知Timer0中断程序,需要发送数据
0222 91800089 LDS R24,InterruptFlag
0224 6082 ORI R24,2
0225 93800089 STS InterruptFlag,R24
(0094) break;
0227 C095 RJMP 0x02BD
(0095) }
(0096)
(0097) case 'r'://读取AT2402(或者另外一块模拟AT2402的8Mega2#)EEPROM
(0098) {
(0099) charInput=getchar();//无用的前导空格字符
0228 DF4D RCALL _getchar
0229 2EC0 MOV R12,R16
(0100) for(i=0;i<4;i++)//将4位(0~4995)BCD转换为为integer
022A 2766 CLR R22
022B C010 RJMP 0x023C
(0101) {
(0102) charInput=getchar()-48;
022C DF49 RCALL _getchar
022D 2F80 MOV R24,R16
022E 5380 SUBI R24,0x30
022F 2EC8 MOV R12,R24
(0103) val+=charInput*temp;
0230 2F08 MOV R16,R24
0231 2711 CLR R17
0232 0195 MOVW R18,R10
0233 D1CA RCALL empy16s
0234 0F40 ADD R20,R16
0235 1F51 ADC R21,R17
(0104) temp/=10;
0236 E02A LDI R18,0xA
0237 E030 LDI R19,0
0238 0185 MOVW R16,R10
0239 D1AA RCALL div16u
023A 0158 MOVW R10,R16
023B 9563 INC R22
023C 3064 CPI R22,4
023D F370 BCS 0x022C
(0105) }
(0106) ExtendRomAddr=val;
023E 9340008F STS ExtendRomAddr,R20
(0107) ExtendRomRW|=0b00000010;//通知Main程序,需要发送At2402(或者Mega8 2#)EEPROM数据
0240 91800060 LDS R24,ExtendRomRW
0242 6082 ORI R24,2
0243 93800060 STS ExtendRomRW,R24
(0108) break;
0245 C077 RJMP 0x02BD
(0109) }
(0110)
(0111) case 'W'://写入片内EEPROM
(0112) {
(0113) charInput=getchar();//无效的空格字符
0246 DF2F RCALL _getchar
0247 2EC0 MOV R12,R16
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -