[求助]
关于STC89C52和AT89S52的不同
刚编写了一个收音机程序,烧录STC可以使用,但是烧录AT后没法正常工作,这是什么原因。下面是写的程序(分模块写的)
- /******************************************************************
- * *
- * K1--- 向上搜索电台 K2--- 向下搜索电台 *
- * K3--- 音量加 K4--- 音量减 *
- * *
- *****************************************************************/
- #include
- #include
- #include "lcd.h"
- #include "IIC.h"
- #include "delay.h"
- sbit K1 = P2^1;
- sbit K2 = P2^2;
- sbit K3 = P2^3;
- sbit K4 = P2^4;
-
- unsigned long frequency;
- // RDA5807 寄存器
- unsigned char RDA_reg_data[8] =
- {
- 0xd0,0x00, // 02H
- 0x00,0x00, // 03H
- 0x00,0x40, // 04H
- 0x90,0x88, // 05H
- };
- unsigned char code cdis1[ ] = {"FM STEREO RADIO "};
- unsigned char code cdis2[ ] = {"FM VOL "};
- char code reserve[3]_at_ 0x3b; //保留0x3b开始的3个字节
- /**********************************************************
- 连续写寄存器子函数
- **********************************************************/
- void RDA5807_write_reg(void)
- {
- uchar i;
- I2C_start();
- // 收音模块写入操作
- I2C_write_byte(0x20);
- // 寄存器连续写操作
- for(i=0; i<8; i++)
- {
- I2C_write_byte(RDA_reg_data[i]);
- }
- I2C_stop();
- }
- /**********************************************************
- 连续读寄存器子函数
- **********************************************************/
- void RDA5807_read_reg(uchar *reg_buf)
- {
- I2C_start();
- // 收音模块读取操作
- I2C_write_byte(0x21);
- // 寄存器连续读操作
- reg_buf[0] = I2C_read_byte(I2C_ACK);
- reg_buf[1] = I2C_read_byte(I2C_ACK);
- reg_buf[2] = I2C_read_byte(I2C_ACK);
- reg_buf[3] = I2C_read_byte(I2C_NACK);
- I2C_stop();
- }
- /**********************************************************
- 模块上电初始化子函数
- **********************************************************/
- void RDA5807_power(void)
- {
- delayms(50);
- // 发送软件复位指令
- RDA_reg_data[0] = 0x00;
- RDA_reg_data[1] = 0x02;
- RDA5807_write_reg();
- delayms(10);
- // 收音模块默认参数
- RDA_reg_data[0] = 0xd0;
- RDA_reg_data[1] = 0x01;
- RDA5807_write_reg();
- }
- /**********************************************************
- 功能描述:收音模块自动寻台模式
- **********************************************************/
- void RDA5807_FM_seek(void)
- {
- uint chan;
- uchar reg_data[4] = {0x00, 0x00, 0x00, 0x00};
- RDA_reg_data[3] &= ~(1 << 4); //调谐禁用
- // 内部自动寻台使能
- RDA_reg_data[0] |= (1 << 0); //SEEK位置1
- RDA5807_write_reg();
- // 等待STC 标志置位
- while(0 == (reg_data[0] & 0x40))
- {
- delayms(20);
- // 读取内部状态
- RDA5807_read_reg(reg_data);
- }
- // 获取当前工作频点
- chan = reg_data[0] & 0x03;
- chan = reg_data[1] | (chan << 8);
- chan = chan << 6;
- // 保存当前工作频点
- RDA_reg_data[2] = (chan >> 8) & 0xff;
- RDA_reg_data[3] = (chan & 0xff);
- }
- /**********************************************************
- 频率显示子函数
- **********************************************************/
- void show_frequency(void)
- {
- unsigned char i,display[5];
- unsigned int temp;
- temp = (RDA_reg_data[2]*256)+(RDA_reg_data[3]&0xc0); //计算
- temp = temp>>6;
- frequency = (unsigned long)(100*temp+87000)/100;
- for(i=0; i<5; i++) // 清显存单元
- display[i] = 0x00;
- display[0] = (frequency)/1000 ; //数据转换
- display[1] = (frequency%1000)/100;
- display[2] = (frequency%100)/10;
- display[3] = 0x2e; //小数点
- display[4] = (frequency%10);
- if(display[0] == 0)
- {
- display[0] = display[1]+0x30;
- display[1] = display[2]+0x30;
- display[2] = display[3];
- display[3] = display[4]+0x30;
- display[4] = 0x20;
- }
- else
- {
- display[0] += 0x30;
- display[1] += 0x30;
- display[2] += 0x30;
- display[4] += 0x30;
- }
- lcd_pos_xy(3,2); //频率显示
- lcd_wdat(display[0]);
- lcd_wdat(display[1]);
- lcd_wdat(display[2]);
- lcd_wdat(display[3]);
- lcd_wdat(display[4]);
- }
- /**********************************************************
- 音量显示子函数
- **********************************************************/
- void show_volume()
- {
- unsigned char temp,display[2];
- temp = RDA_reg_data[7] & 0x0f; //取音量值
- display[0] = temp/10;
- display[1] = temp%10;
- if(display[0] == 0) //如果高位为0
- {
- display[0] = display[1]; //低位显存内容进入高位显存
- display[1] = 0x20; //低位不显示
- }
- else
- {
- display[1] += 0x30;
- }
- display[0] += 0x30;
- lcd_pos_xy(13,2); //音量值显示
- lcd_wdat(display[0]);
- lcd_wdat(display[1]);
- }
- /**********************************************************
- 主函数
- **********************************************************/
- void main(void)
- {
- P0 = 0xff;
- P1 = 0xff;
- P2 = 0xff;
- lcd_init();
- lcd_w_string(0,1,cdis1,0);
- lcd_w_string(0,2,cdis2,0);
- RDA5807_power();
- while(1)
- {
- if(K1 == 0)
- {
- delayms(20);
- if(K1 == 0)
- {
- RDA_reg_data[0] |= (1 << 1); //SEEK UP
- RDA5807_FM_seek();
- while(K1 == 0);
- }
- }
- if(K2 == 0)
- {
- delayms(20);
- if(K2 == 0)
- {
- RDA_reg_data[0] &= ~(1 << 1); //SEEK DOWN
- RDA5807_FM_seek();
- while(K2 == 0);
- }
- }
- if(K3 == 0)
- {
- delayms(20);
- if(K3 == 0)
- {
- if((RDA_reg_data[7] & 0x0f) < 0x0f)
- {
- RDA_reg_data[0] = 0xd0;
- RDA_reg_data[1] = 0x01;
- RDA_reg_data[3] &= ~(1 << 4);
- RDA_reg_data[7]++; // 音量递增
- RDA5807_write_reg();
- while(K3 == 0);
- }
- }
- }
- if(K4 == 0)
- {
- delayms(20);
- if(K4 == 0)
- {
- if((RDA_reg_data[7] & 0x0f) > 0x00)
- {
- RDA_reg_data[0] = 0xd0;
- RDA_reg_data[1] = 0x01;
- RDA_reg_data[3] &= ~(1 << 4);
-
- RDA_reg_data[7]--; // 音量递减
- RDA5807_write_reg();
- while(K4 == 0);
- }
- }
- }
- show_volume();
- show_frequency();
- }
- }
- /*********************************************************/
- #include
- #include "lcd.h"
- #include "delay.h"
-
- #define uchar unsigned char
- #define uint unsigned int
- #define DATA_PORT P1
- sbit LCD_RS = P0^0;
- sbit LCD_RW = P0^1;
- sbit LCD_EN = P0^2;
- /*******************************************************************
- 检查LCD忙状态
- lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。
- *******************************************************************/
- bit lcd_busy()
- {
- bit result;
- LCD_RS = 0;
- LCD_RW = 1;
- LCD_EN = 1;
- delayNOP();
- result = (bit)(DATA_PORT&0x80);
- LCD_EN = 0;
- return(result);
- }
- /*******************************************************************
- 写指令数据到LCD
- RS=L,RW=L,E=高脉冲,D0-D7=指令码。
- Check=1,进行忙检测。
- *******************************************************************/
- void lcd_wcmd(uchar cmd, bit Check)
- {
- if(Check)
- while(lcd_busy());
- LCD_RS = 0;
- LCD_RW = 0;
- LCD_EN = 0;
- delayNOP();
- DATA_PORT = cmd;
- delayNOP();
- LCD_EN = 1;
- delayNOP();
- LCD_EN = 0;
- }
- /*******************************************************************
- 写显示数据到LCD
- RS=H,RW=L,E=高脉冲,D0-D7=数据。
- *******************************************************************/
- void lcd_wdat(uchar dat)
- {
- while(lcd_busy()); //进行忙检测
- LCD_RS = 1;
- LCD_RW = 0;
- LCD_EN = 0;
- DATA_PORT = dat;
- delayNOP();
- LCD_EN = 1;
- delayNOP();
- LCD_EN = 0;
- }
- /*******************************************************************
- LCD初始化设定
- *******************************************************************/
- void lcd_init()
- {
- delayms(50);
- lcd_wcmd(0x38,0); //16*2显示,5*7点阵,8位数据
- delayms(5);
- lcd_wcmd(0x38,0); //不进行忙检测,强制执行。
- delayms(5);
- lcd_wcmd(0x38,0);
- delayms(5);
- lcd_wcmd(0x38,1); //进行忙检测
- delayms(5);
- lcd_wcmd(0x0c,1); //显示开,关光标
- delayms(5);
- lcd_wcmd(0x06,1); //移动光标
- delayms(5);
- lcd_wcmd(0x01,1); //清除LCD的显示内容
- delayms(5);
- }
- /*******************************************************************
- 设定显示位置
- *******************************************************************/
- void lcd_pos_xy(uchar pos_x,uchar pos_y)
- {
- uchar pos_temp;
- pos_temp=pos_x & 0x0f;
- pos_y &= 0x0f;
- if(pos_y==0x01)
- pos_temp |= 0x80;
- else
- if(pos_y==0x02)
- pos_temp |= 0xc0;
- lcd_wcmd(pos_temp,1);
- }
- /*******************************************************************
- 写字符串子函数
- *******************************************************************/
- void lcd_w_string(uchar pos_x,uchar pos_y,uchar code *str,uint times)
- {
- uchar m;
- lcd_pos_xy(pos_x,pos_y); //设定起始位置
- for(m=0; m<16; m++)
- {
- lcd_wdat(str[m]);
- delayms(times);
- }
- }
- /*****************************************************************
- pos_x 取值范围: 0 - 15
- pos_y 取值范围: 1 - 2
- ******************************************************************/
- #include
- #include "delay.h"
- #include "IIC.h"
- sbit SDA = P2^5;
- sbit SCL = P2^6;
-
- /**********************************************************
- 启动子程序
- 在 SCL 高电平期间 SDA 发生负跳变
- **********************************************************/
- void I2C_start()
- {
- SDA = 1;
- SCL = 1;
- delayNOP();
- SDA = 0;
- delayNOP();
- SCL = 0;
- }
- /**********************************************************
- 停止子函数
- 在 SCL 高电平期间 SDA 发生正跳变
- **********************************************************/
- void I2C_stop()
- {
- SDA = 0;
- SCL = 1;
- delayNOP();
- SDA = 1;
- delayNOP();
- }
- /**********************************************************
- 发送一个字节子程序
- **********************************************************/
- unsigned char I2C_write_byte(unsigned char indata)
- {
- unsigned char i, ack;
- // I2C 发送8 位数据
- for (i=0; i<8; i++)
- {
- // 高在前低在后
- if (indata & 0x80)
- SDA = 1;
- else
- SDA = 0;
- // 发送左移一位
- indata <<= 1;
- delayNOP();
- SCL = 1;
- delayNOP();
- SCL = 0;
- }
- // 设置SDA为输入
- SDA =1;;
- delayNOP();
- // 读取从机应答状态
- SCL = 1;
- delayNOP();
- if(SDA)
- {
- ack = I2C_NACK;
- }
- else
- {
- ack = I2C_ACK;
- }
- SCL = 0;
- return ack;
- }
- /**********************************************************
- 读一个字节子程序
- **********************************************************/
- unsigned char I2C_read_byte(unsigned char ack)
- {
- unsigned char i, data1 = 0;
- // SDA 设置输入方向
- SDA = 1;
- // I2C 接收8位数据
- for(i = 8; i > 0; i--)
- {
- data1 <<= 1;
- SCL = 1;
- delayNOP();
- // 高在前低在后
- if (SDA)
- {
- data1++;
- }
- SCL = 0;
- delayNOP();
- }
- // 主机发送应答状态
- if(ack == I2C_ACK)
- SDA = 0;
- else
- SDA = 1;
- delayNOP();
- SCL = 1;
- delayNOP();
- SCL = 0;
- return data1;
- }
- /*********************************************************/
电路自己焊的还是画的PCB板?如果自己焊的,那么AT的不能工作是正常的,我以前也遇到过。
首先注意资源上的差别,另外注意存储器选择脚一定要接Vcc,即选择片内程序存储器。
上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
回复 沙发jzffzj 的帖子
自己焊的,为什么不能工作?
回复 板凳chunyang 的帖子
程序应该没什么问题吧,因为用STC能正常工作,也没超过AT的内存
回复 5楼小杜在此 的帖子
仔细看器件手册,二者的资源有不同的地方。
上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang