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

📄 1602lcd.lst

📁 1602lcd显示频率计 通过了proteus仿真
💻 LST
📖 第 1 页 / 共 2 页
字号:
__text_start:
__start:
      4C E5CF      LDI	R28,0x5F
      4D E0D4      LDI	R29,4
      4E BFCD      OUT	0x3D,R28
      4F BFDE      OUT	0x3E,R29
      50 51C0      SUBI	R28,0x10
      51 40D0      SBCI	R29,0
      52 EA0A      LDI	R16,0xAA
      53 8308      STD	Y+0,R16
      54 2400      CLR	R0
      55 EAE4      LDI	R30,0xA4
      56 E0F0      LDI	R31,0
      57 E010      LDI	R17,0
      58 3AE7      CPI	R30,0xA7
      59 07F1      CPC	R31,R17
      5A F011      BEQ	0x005D
      5B 9201      ST	R0,Z+
      5C CFFB      RJMP	0x0058
      5D 8300      STD	Z+0,R16
      5E E5E4      LDI	R30,0x54
      5F E0F0      LDI	R31,0
      60 E6A0      LDI	R26,0x60
      61 E0B0      LDI	R27,0
      62 E010      LDI	R17,0
      63 E000      LDI	R16,0
      64 BF0B      OUT	0x3B,R16
      65 39E8      CPI	R30,0x98
      66 07F1      CPC	R31,R17
      67 F021      BEQ	0x006C
      68 95C8      LPM
      69 9631      ADIW	R30,1
      6A 920D      ST	R0,X+
      6B CFF9      RJMP	0x0065
      6C 940E 00FA CALL	_main
_exit:
      6E CFFF      RJMP	_exit
FILE: F:\avr单片机学习\我自编程序\1602lcd\1602lcd.c
(0001) 
(0002) /*---------------------------------------------------------------*/
(0003) #include <iom16v.h>
(0004) #include <macros.h>
(0005) #include "lcd1602.h"
(0006) /*------------------------------------主函数-------------------------------------------*/
(0007) 
(0008) /*------------------------------------液晶驱动函数-------------------------------------*/
(0009) //液晶初始化
(0010) void lcd_init(void)
(0011) {
(0012)  delay_nms(15);
_lcd_init:
      6F E00F      LDI	R16,0xF
      70 E010      LDI	R17,0
      71 D07A      RCALL	_delay_nms
(0013)  lcd_write_command(0x38,0);//显示模式设置三次(此时不管lcd空闲与否)
      72 2722      CLR	R18
      73 E308      LDI	R16,0x38
      74 D01F      RCALL	_lcd_write_command
(0014)  delay_nms(5);
      75 E005      LDI	R16,5
      76 E010      LDI	R17,0
      77 D074      RCALL	_delay_nms
(0015)  lcd_write_command(0x38,0);
      78 2722      CLR	R18
      79 E308      LDI	R16,0x38
      7A D019      RCALL	_lcd_write_command
(0016)  delay_nms(5);
      7B E005      LDI	R16,5
      7C E010      LDI	R17,0
      7D D06E      RCALL	_delay_nms
(0017)  lcd_write_command(0x38,0);
      7E 2722      CLR	R18
      7F E308      LDI	R16,0x38
      80 D013      RCALL	_lcd_write_command
(0018)  delay_nms(5);
      81 E005      LDI	R16,5
      82 E010      LDI	R17,0
      83 D068      RCALL	_delay_nms
(0019)  
(0020)  lcd_write_command(0x38,1);//显示模式设置(从此之后均需lcd空闲)
      84 E021      LDI	R18,1
      85 E308      LDI	R16,0x38
      86 D00D      RCALL	_lcd_write_command
(0021)  lcd_write_command(0x08,1);//显示关闭
      87 E021      LDI	R18,1
      88 E008      LDI	R16,0x8
      89 D00A      RCALL	_lcd_write_command
(0022)  lcd_write_command(0x01,1);//显示清屏
      8A E021      LDI	R18,1
      8B E001      LDI	R16,1
      8C D007      RCALL	_lcd_write_command
(0023)  lcd_write_command(0x06,1);//显示光标移动设置
      8D E021      LDI	R18,1
      8E E006      LDI	R16,6
      8F D004      RCALL	_lcd_write_command
(0024)  lcd_write_command(0x0c,1);//显示开及光标设置
      90 E021      LDI	R18,1
      91 E00C      LDI	R16,0xC
      92 D001      RCALL	_lcd_write_command
      93 9508      RET
_lcd_write_command:
  wait_en              --> R12
  command              --> R10
      94 92AA      ST	R10,-Y
      95 92CA      ST	R12,-Y
      96 2EC2      MOV	R12,R18
      97 2EA0      MOV	R10,R16
(0025) }
(0026) 
(0027) //写指令函数: E=高脉冲 RS=0 RW=0
(0028) void lcd_write_command(unsigned char command,unsigned char wait_en)//command为指令,wait_en指定是否要检测LCD忙信号
(0029) {
(0030)  if(wait_en)wait_enable();//若wait_en为1,则要检测LCD忙信号,等待其空闲
      98 20CC      TST	R12
      99 F009      BEQ	0x009B
      9A D016      RCALL	_wait_enable
(0031)  lcd_control_port&=~lcd_RS;//RS=0
      9B 98D8      CBI	0x1B,0
(0032)  lcd_control_port&=~lcd_RW;//RW=0
      9C 98D9      CBI	0x1B,1
(0033)  lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
      9D 98DA      CBI	0x1B,2
(0034)  NOP();
      9E 0000      NOP
(0035)  lcd_control_port|=lcd_EN;//E=1
      9F 9ADA      SBI	0x1B,2
(0036)  lcd_data_port=command;
      A0 BAA2      OUT	0x12,R10
(0037)  lcd_control_port&=~lcd_EN;//重设E=0
      A1 98DA      CBI	0x1B,2
      A2 90C9      LD	R12,Y+
      A3 90A9      LD	R10,Y+
      A4 9508      RET
_lcd_write_data:
  char_data            --> R10
      A5 92AA      ST	R10,-Y
      A6 2EA0      MOV	R10,R16
(0038) }
(0039) 
(0040) //写数据函数: E =高脉冲 RS=1 RW=0
(0041) void lcd_write_data(unsigned char char_data)
(0042) {
(0043)  wait_enable();//等待LCD空闲
      A7 D009      RCALL	_wait_enable
(0044)  lcd_control_port|=lcd_RS;//RS=1
      A8 9AD8      SBI	0x1B,0
(0045)  lcd_control_port&=~lcd_RW;//RW=0
      A9 98D9      CBI	0x1B,1
(0046)  lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
      AA 98DA      CBI	0x1B,2
(0047)  NOP();
      AB 0000      NOP
(0048)  lcd_control_port|=lcd_EN;//E=1
      AC 9ADA      SBI	0x1B,2
(0049)  lcd_data_port=char_data;
      AD BAA2      OUT	0x12,R10
(0050)  lcd_control_port&=~lcd_EN;//重设E=0
      AE 98DA      CBI	0x1B,2
      AF 90A9      LD	R10,Y+
      B0 9508      RET
(0051) }
(0052) 
(0053) //正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1;DB7: 0 LCD控制器空闲,1 LCD控制器忙。
(0054) //检测忙信号,等待LCD空闲函数
(0055) void wait_enable(void)
(0056) {
(0057)  lcd_busy_ddr&=~busy;//设置busy口为输入
_wait_enable:
      B1 988F      CBI	0x11,7
(0058)  lcd_control_port&=~lcd_RS;//RS=0
      B2 98D8      CBI	0x1B,0
(0059)  lcd_control_port|=lcd_RW;//RW=1
      B3 9AD9      SBI	0x1B,1
(0060)  NOP();
      B4 0000      NOP
(0061)  lcd_control_port|=lcd_EN;//E=1
      B5 9ADA      SBI	0x1B,2
(0062)  //while(lcd_busy_pin&busy);//等待LCD_DB7为0/////////////////////////
(0063)  lcd_control_port&=~lcd_EN;//重设E=0
      B6 98DA      CBI	0x1B,2
(0064)  lcd_busy_ddr|=busy;//设置busy口为输出
      B7 9A8F      SBI	0x11,7
      B8 9508      RET
_display_a_char:
  position_tem         --> R20
  char_data            --> R10
  position             --> R22
      B9 940E 0215 CALL	push_xgsetF00C
      BB 2EA2      MOV	R10,R18
      BC 2F60      MOV	R22,R16
(0065) }
(0066) 
(0067) //指定位置显示一个字符:第一行位置0~15,第二行16~31
(0068) //显示一个字符函数
(0069) void display_a_char(unsigned char position,unsigned char char_data)//参数position指定位置0~31,char_data为要显示的字符
(0070) {
(0071)  unsigned char position_tem;
(0072)  if(position>=0x10)
      BD 3160      CPI	R22,0x10
      BE F018      BCS	0x00C2
(0073)  position_tem=position+0xb0;///////////
      BF 2F46      MOV	R20,R22
      C0 5540      SUBI	R20,0x50
      C1 C002      RJMP	0x00C4
(0074)  else
(0075)  position_tem=position+0x80;
      C2 2F46      MOV	R20,R22
      C3 5840      SUBI	R20,0x80
(0076)  lcd_write_command(position_tem,1);
      C4 E021      LDI	R18,1
      C5 2F04      MOV	R16,R20
      C6 DFCD      RCALL	_lcd_write_command
(0077)  lcd_write_data(char_data);
      C7 2D0A      MOV	R16,R10
      C8 DFDC      RCALL	_lcd_write_data
      C9 940C 021C JMP	pop_xgsetF00C
_display_a_string:
  col_tem              --> R22
  i                    --> R20
  ptr                  --> R10
  col                  --> R20
      CB 940E 0215 CALL	push_xgsetF00C
      CD 0159      MOVW	R10,R18
      CE 2F40      MOV	R20,R16
(0078) }
(0079) 
(0080) //指定一行显示连续字符串:0显示在第一行,1显示在第二行,注字符串不能长于16个字符
(0081) //显示一行连续字符串函数
(0082) void display_a_string(unsigned char col,unsigned char *ptr)//参数col指定行,*ptr指字符串数组的首指针
(0083) {
(0084)  unsigned char col_tem,i;
(0085)  col_tem=col<<4;//若col为1(即在LCD第二行显示字符串),先把col左移4位,使显示字符的首位置改到第二行首位,即位置16
      CF 2F64      MOV	R22,R20
      D0 706F      ANDI	R22,0xF
      D1 9562      SWAP	R22
(0086)  for(i=0;i<16;i++)
      D2 2744      CLR	R20
      D3 C00A      RJMP	0x00DE
(0087)  display_a_char(col_tem++,*(ptr+i));
      D4 2FE4      MOV	R30,R20
      D5 27FF      CLR	R31
      D6 0DEA      ADD	R30,R10
      D7 1DFB      ADC	R31,R11
      D8 8120      LDD	R18,Z+0
      D9 2E26      MOV	R2,R22
      DA 5F6F      SUBI	R22,0xFF
      DB 2D02      MOV	R16,R2
      DC DFDC      RCALL	_display_a_char
      DD 9543      INC	R20
      DE 3140      CPI	R20,0x10
      DF F3A0      BCS	0x00D4
      E0 940C 021C JMP	pop_xgsetF00C
(0088) }
(0089) 
(0090) /*---------------------------------------延时函数-------------------------------------*/
(0091) //1ms延时函数
(0092) void delay_1ms(void)
(0093) {
(0094)  unsigned int i;
(0095)  for(i=0;i<600;i++);
_delay_1ms:
  i                    --> R16
      E2 2700      CLR	R16
      E3 2711      CLR	R17
      E4 C002      RJMP	0x00E7
      E5 5F0F      SUBI	R16,0xFF
      E6 4F1F      SBCI	R17,0xFF
      E7 3508      CPI	R16,0x58
      E8 E0E2      LDI	R30,2
      E9 071E      CPC	R17,R30
      EA F3D0      BCS	0x00E5
      EB 9508      RET
_delay_nms:
  i                    --> R20
  n                    --> R10
      EC 940E 020B CALL	push_xgset300C
      EE 0158      MOVW	R10,R16
(0096) }
(0097) 
(0098) //n ms延时函数
(0099) void delay_nms(unsigned int n)
(0100) {
(0101)  unsigned int i;
(0102)  for(i=0;i<n;i++)delay_1ms();
      EF 2744      CLR	R20
      F0 2755      CLR	R21
      F1 C003      RJMP	0x00F5
      F2 DFEF      RCALL	_delay_1ms
      F3 5F4F      SUBI	R20,0xFF
      F4 4F5F      SBCI	R21,0xFF
      F5 154A      CP	R20,R10
      F6 055B      CPC	R21,R11
      F7 F3D0      BCS	0x00F2
      F8 940C 0210 JMP	pop_xgset300C
FILE: F:\avr单片机学习\我自编程序\1602lcd\main.c
(0001) /*---------------------------------------------------------------
(0002) 工程名称:1602液晶演示频率计
(0003) 编译器类型及版本:ICCAVR 6.9
(0004) 设计者:余威明
(0005) 设计日期:2007.08.09
(0006) 
(0007) 芯片类型:ATmega16L
(0008) 时钟频率:4M外部时钟
(0009) 硬件接口说明:MCU  ~  LCD
(0010)               PORTD ~  dataport对应1602的d0~d7
(0011)               PA1  ~  RS
(0012)               PA2  ~  RW
(0013)               PA3  ~  E
(0014) ---------------------------------------------------------------*/
(0015) #include <iom16v.h>
(0016) #include <macros.h>
(0017) #include "lcd1602.h"
(0018) 
(0019) 
(0020) void hextoasc(void);    //十六进制转ASCII码
(0021) void timer1_init(void); //定时器1初始化
(0022) void port_init(void);   //端口初始化
(0023) void init_devices(void);
(0024) 
(0025) //显示的两行字符
(0026) unsigned char str00[]="  author:ancient";   //液晶屏初始显示内容
(0027) unsigned char str01[]=" time:2008/08/09";
(0028) unsigned char str1[]=" frequency meter";
(0029) unsigned char str2[]="    F:000HZ     ";    //频率显示形式
(0030) unsigned int count;                      //外部脉冲计数值
(0031) unsigned char tim0_ovf_count;            //t0溢出次数
(0032) //在LCD上显示两行字符
(0033) 
(0034) 
(0035) void main(void)
(0036) {
(0037)  init_devices();    //初始化
_main:
      FA D08B      RCALL	_init_devices
(0038)  display_a_string(0,str00);   //开机界面
      FB E620      LDI	R18,0x60
      FC E030      LDI	R19,0
      FD 2700      CLR	R16
      FE 940E 00CB CALL	_display_a_string
(0039)     delay_nms(500);
     100 EF04      LDI	R16,0xF4
     101 E011      LDI	R17,1
     102 940E 00EC CALL	_delay_nms
(0040)  display_a_string(1,str01);
     104 E721      LDI	R18,0x71
     105 E030      LDI	R19,0
     106 E001      LDI	R16,1
     107 940E 00CB CALL	_display_a_string
(0041)    delay_nms(1000);
     109 EE08      LDI	R16,0xE8
     10A E013      LDI	R17,3
     10B 940E 00EC CALL	_delay_nms
(0042)  lcd_write_command(0x01,1);//显示清屏
     10D E021      LDI	R18,1
     10E E001      LDI	R16,1
     10F 940E 0094 CALL	_lcd_write_command
(0043)  delay_nms(200);

⌨️ 快捷键说明

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