|

楼主 |
发表于 2014-9-26 15:43:05
|
显示全部楼层
好了,该上单片机的软件了,kc环境下c语言编写- #include <REG51.H>
- #include <intrins.h>
- //#define BAUD 0xFF40 //38400bps @ 22.1184MHz
- #define BAUD 0xFD00// STC15F104的串行波特率9600bps @ 22.1184MHz时钟
- sfr AUXR = 0x8E;//定时器模式寄存器
- sbit RXB = P3^0; //定义串口的2个I/O管脚
- sbit TXB = P3^1;
- //和AD9850/51的通信接口
- sbit ad9850_w_clk =P3^2;//接ad9850的w_clk脚/PIN7
- sbit ad9850_fq_up =P3^3;//接ad9850的fq_up脚/PIN8
- sbit ad9850_bit_data =P3^4;//接ad9850的D7脚/PIN25
- sbit ad9850_rest =P3^5;//接ad9850的rest脚/PIN12
- //-----STC15F104的EEprom用于掉电记忆和脱离电脑工作-------
- sfr IAP_DATA = 0xC2;//IAP数据寄存器
- sfr IAP_ADDRH = 0xC3;//IAP地址寄存器高字节
- sfr IAP_ADDRL = 0xC4;//IAP地址寄存器低字节
- sfr IAP_CMD = 0xC5;//IAP命令寄存器
- sfr IAP_TRIG = 0xC6;//IAP命令触发寄存器
- sfr IAP_CONTR = 0xC7;//IAP控制寄存器
- //写入首地址
- #define IAP_ADDRESS 0x0400
- #define CMD_IDLE 0//空闲模式
- #define CMD_READ 1//IAP字节读命令
- #define CMD_PROGRAM 2//IAP字节编程命令
- #define CMD_ERASE 3//IAP扇区擦除命令
- #define ENABLE_IAP 0x81//if SYSCLK<24MHz
- //-----------------------------------------------
- unsigned char TBUF;//RBUF;
- unsigned char TDAT,RDAT;
- unsigned char TCNT,RCNT;
- unsigned char TBIT,RBIT;
- bit TING,RING;
- bit TEND,REND;
- unsigned char TmpF[6]={0x0f,0x00,0x01,0x00,0x00,0x00};
- unsigned char W[5];
- unsigned char i,j;
- //芯片控制函数
- void ad_reset();
- void ad_write();
- void answer();
- //---------------EEprom------------------
- //void Delay(unsigned char n);
- void IapIdle();
- unsigned char IapReadByte(unsigned int addr);
- void IapWriteByte(unsigned int addr, unsigned char dat);
- void IapEraseSector(unsigned int addr);
- //-----------------------------------------------
- main ()
- {
- P3=0x03;//初始化管脚口
- TMOD = 0x00;
- AUXR = 0x80; //timer0 工作在1T模式
- TL0 = BAUD;
- TH0 = BAUD>>8;
- TR0 = 1;
- ET0 = 1;
- PT0 = 1;
- EA = 1;
- //初始化串口设置
- TING = 0;
- RING = 0;
- TEND = 1;
- REND = 0;
- TCNT = 0;
- RCNT = 0;
- j=0;
- ad_reset();//AD985X芯片复位准备
- // ad_write();//ce shi
- for (i=0;i<5;i++) W[i]=IapReadByte(IAP_ADDRESS+i);
- for (i=0; i<5; i++) TmpF[i] = W[i];
- TmpF[5]=0x83;
- //使芯片开始工作
- while( 1 )
- {
- //while (!REND);
- switch (TmpF[5])
- {
- case 0x80://读取
- //W[0]=0x01;
- TmpF[5]=0x01;
- answer();//向Pc发送数据回答
- //j=0;
- break;
- case 0x81://联机
- //W[0]=0x02;
- TmpF[5]=0x02;
- answer();
- //j=0;
- break;
- case 0x82://复位
- //W[0]=0x03;
- TmpF[5]=0x03;
- ad_reset();
- answer();
- //j=0;
- break;
- case 0x83://置频
- //W[0]=0x04;
- TmpF[5]=0x04;
- ad_reset();//AD985X芯片复位准备
- ad_write();
- answer();
- break;
- case 0x84://写入
- //W[0]=0x05;
- TmpF[5]=0x05;
- IapEraseSector(IAP_ADDRESS);//扇区擦除
- for (i=0;i<5;i++)
- {
- IapWriteByte(IAP_ADDRESS+i, W[i]);
- }
- answer();
- //写ISP/IAP/EEPROM数据
- break;
- case 0x85://扫频
- //W[0]=0x06;
- TmpF[5]=0x06;
-
- break;
- }
- if(j>=6)
- {
- j=0 ;
- for (i=0; i<5; i++) W[i]=TmpF[i];
- }
- }
- }
- //发送数据到串口
- void answer()
- {
- for (i=0; i<6; i++)//发6个字节
- {
- while (!TEND);
- TEND = 0;
- TBUF = TmpF[i];
- TING = 1;//发送数据到串口
- }
- }
- //定时器模拟串口
- void tm0() interrupt 1 using 1
- {
- if (RING)
- {
- if (--RCNT == 0)
- {
- RCNT = 3; //复位发送波特率计数器
- if (--RBIT == 0)
- {
- TmpF[j] = RDAT;//保存数据到RBUF
- RING = 0; //停止接收
- REND = 1; //接收完成标记
- j++ ;
- }
- else
- {
- RDAT >>= 1;
- if (RXB) RDAT |= 0x80;
- }
- }
- }
- else if (!RXB)
- {//检测接收脚电平
- RING = 1; //set start receive flag
- RCNT = 4; //初始化波特率计数器
- RBIT = 9; //initial receive bit number (8 data bits + 1 stop bit)
- }
- if (--TCNT == 0)
- {
- TCNT = 3;
- if (TING)
- {
- if (TBIT == 0)
- {
- TXB = 0;
- TDAT = TBUF;
- TBIT = 9;
- }
- else
- {
- TDAT >>= 1;
- if (--TBIT == 0)
- {
- TXB = 1;
- TING = 0;
- TEND = 1;
- }
- else
- {
- TXB = CY;
- }
- }
- }
- }
- }
- //***************************************************//
- // ad9850复位(串行模式) //
- //---------------------------------------------------//
- void ad_reset()
- {
- ad9850_w_clk=0;
- ad9850_fq_up=0;
- //rest信号
- ad9850_rest=0;
- ad9850_rest=1;
- ad9850_rest=0;
- //w_clk信号
- ad9850_w_clk=0;
- ad9850_w_clk=1;
- ad9850_w_clk=0;
- //fq_up信号
- ad9850_fq_up=0;
- ad9850_fq_up=1;
- ad9850_fq_up=0;
- }
- //***************************************************//
- // 向ad9850中写命令与数据(串行) //
- //---------------------------------------------------//
- void ad_write()
- {
- unsigned char ji;
- for(ji=0;ji<5;ji++)
- {
- for(i=0;i<8;i++)//写w数据
- {
- ad9850_bit_data=(W[ji]>>i)&0x01;
- ad9850_w_clk=1;
- ad9850_w_clk=0;
- }
- }
- ad9850_fq_up=1;//移入始能
- ad9850_fq_up=0;
- }//完成
- /*----------------------------
- EEprom 软件延时
- ----------------------------*/
- /*
- void Delay(unsigned char n)
- {
- unsigned int x;
- while (n--)
- {
- x = 0;
- while (++x);
- }
- }
- */
- /*----------------------------
- 关闭IAP
- ----------------------------*/
- void IapIdle()
- {
- IAP_CONTR = 0; //关闭IAP功能
- IAP_CMD = 0; //清除命令寄存器
- IAP_TRIG = 0; //清除触发寄存器
- IAP_ADDRH = 0x80;//将地址设置到非IAP区域
- IAP_ADDRL = 0;
- }
- /*----------------------------
- 从ISP/IAP/EEPROM区域读取一字节
- ----------------------------*/
- unsigned char IapReadByte(unsigned int addr)
- {
- unsigned char dat; //数据缓冲区
- IAP_CONTR = ENABLE_IAP;//使能IAP
- IAP_CMD = CMD_READ; //设置IAP命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_(); //等待ISP/IAP/EEPROM操作完成
- dat = IAP_DATA; //读ISP/IAP/EEPROM数据
- IapIdle(); //关闭IAP功能
- return dat; //返回
- }
- /*----------------------------
- 写一字节数据到ISP/IAP/EEPROM区域
- ----------------------------*/
- void IapWriteByte(unsigned int addr, unsigned char dat)
- {
- IAP_CONTR = ENABLE_IAP;//使能IAP
- IAP_CMD = CMD_PROGRAM; //设置IAP命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_DATA = dat; //写ISP/IAP/EEPROM数据
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_(); //等待ISP/IAP/EEPROM操作完成
- IapIdle();
- }
- /*----------------------------
- 扇区擦除
- ----------------------------*/
- void IapEraseSector(unsigned int addr)
- {
- IAP_CONTR = ENABLE_IAP;//使能IAP
- IAP_CMD = CMD_ERASE; //设置IAP命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_(); //等待ISP/IAP/EEPROM操作完成
- IapIdle();
- }
复制代码 |
|