日照高科園
所有的底層驅動
綠色的是MAP映射
藍色的是程序
/*
*****************************************************************
This article is the official reference PL3201 Manual do address mapping,
Author: 小ARM菜菜
Time: April 3, 2013
Description: The system file
Copyright @ 小ARM菜菜
Q Q: 925295580
*****************************************************************
*/
sfr P0 = 0x80;
sfr P1 = 0x90;
sfr P2 = 0xA0;
sfr P3 = 0xB0;
sfr PSW = 0xD0;
sfr ACC = 0xE0;
sfr B = 0xF0;
sfr SP = 0x81;
sfr DPL = 0x82;
sfr DPH = 0x83;
sfr PCON = 0x87;
sfr TCON = 0x88;
sfr TMOD = 0x89;
sfr TMOD1 = 0xC9;
sfr TL0 = 0x8A;
sfr TL1 = 0x8B;
sfr TH0 = 0x8C;
sfr TH1 = 0x8D;
sfr IE = 0xA8;
sfr IP = 0xB8;
sfr SCON = 0x98;
sfr SBUF = 0x99;
sfr TCON1 = 0xC8;
sfr RCAP2L = 0xCA;
sfr RCAP2H = 0xCB;
sfr TL2 = 0xCC;
sfr TH2 = 0xCD;
sfr16 DPTR = 0x82;
//sys
sfr STATUS = 0x87;
sfr WDT_RST = 0x8F;
sfr RS485_RST = 0xDA;
sfr ACC_H = 0xEA;
sfr B_H = 0xF1;
sfr EIP = 0xB9;
sfr EIE = 0xA9;
//串口1
sfr SCON1 = 0xC0;
sfr SBUF1 = 0xC1;
sfr CKCON = 0x8E; //時鐘控制
sfr IR_CNT = 0xDB; //紅外控制
//RTC
sfr EXT_ADR = 0xD9;
sfr EXT_DAT = 0xD8;
sfr EXT_CTRL = 0xFD;
//載波通信寄存器
sfr SSC_DAT = 0xF8;
sfr SSC_ADR = 0xF9;
sfr SSC_BUF = 0xFA;
//PMU
sfr PMU_DAT = 0xE8;
sfr PMU_ADR = 0xE9;
/* BIT Registers */
/* PSW */
sbit CY = PSW^7;
sbit AC = PSW^6;
sbit F0 = PSW^5;
sbit RS1 = PSW^4;
sbit RS0 = PSW^3;
sbit OV = PSW^2;
sbit ALU_MOD = PSW^1; // 8位/16位運算模式選擇??
sbit P = PSW^0;
/* TCON */
sbit TF1 = TCON^7;
sbit TR1 = TCON^6;
sbit TF0 = TCON^5;
sbit TR0 = TCON^4;
sbit IE1 = TCON^3;
sbit IT1 = TCON^2;
sbit IE0 = TCON^1;
sbit IT0 = TCON^0;
/* IE */
sbit EA = IE^7;
sbit ES1 = IE^6;
sbit ET2 = IE^5; //8052 only
sbit ES = IE^4;
sbit ET1 = IE^3;
sbit EX1 = IE^2;
sbit ET0 = IE^1;
sbit EX0 = IE^0;
/* IP */
sbit PT2 = IP^5;
sbit PS = IP^4;
sbit PT1 = IP^3;
sbit PX1 = IP^2;
sbit PT0 = IP^1;
sbit PX0 = IP^0;
/* P3 */
sbit RD = P3^7;
sbit WR = P3^6;
sbit T1 = P3^5;
sbit T0 = P3^4;
sbit INT1 = P3^3;
sbit INT0 = P3^2;
sbit TXD = P3^1;
sbit RXD = P3^0;
/* SCON */
sbit SM0 = SCON^7;
sbit SM1 = SCON^6;
sbit SM2 = SCON^5;
sbit REN = SCON^4;
sbit TB8 = SCON^3;
sbit RB8 = SCON^2;
sbit TI = SCON^1;
sbit RI = SCON^0;
/* SCON1 */
sbit ESM0 = SCON1^7;
sbit ESM1 = SCON1^6;
sbit ESM2 = SCON1^5;
sbit EREN = SCON1^4;
sbit ETB8 = SCON1^3;
sbit ERB8 = SCON1^2;
sbit ETI = SCON1^1;
sbit ERI = SCON1^0;
/* P1 */
sbit T2EX = P1^1; // 8052 only
sbit T2 = P1^0; // 8052 only
/* T2CON TCON1*/
sbit TF2 = TCON1^5;
sbit TR2 = TCON1^4;
sbit IE2 = TCON1^1;
sbit IT2 = TCON1^0;
// Time Adjust Register
#define Time_Adjust_Register 0x80
// Second Register
#define Second_Register 0x81
// Minute Register
#define Minute_Register 0x82
// Hour Register
#define Hour_Register 0x83
// Week Register
#define Week_Register 0x84
// Day Register
#define Day_Register 0x85
// Month Register
#define Month_Register 0x86
// Year Register
#define Year_Register 0x87
// Write Protect Register
#define Write_Protect_Register 0xff
/*
ATT7035BU寄存器描述
小ARM菜菜
QQ:925295580
*/
//電流通道1 的ADC 采樣數據
#define Spl_I1 0x00
//電流通道2 的ADC 采樣數據
#define Spl_I2 0x01
//電壓通道的ADC 采樣數據
#define Spl_U 0x02
//電流通道1 的有效值
#define Rms_I1 0x06
//電流通道2 的有效值
#define Rms_I2 0x07
//電壓通道的有效值
#define Rms_U 0x08
//電壓頻率 2個字節
#define Freq_U 0x09
//第一通道有功功率
#define PowerP1 0x0A
//第一通道無功功率
#define PowerQ1 0x0B
//視在功率
#define Power_S 0x0C
//有功能量
#define Energy_P 0x0D
//無功能量
#define Energy_Q 0x0E
//視在能量
#define Energy_S 0x0F
//第二通道有功功率
#define PowerP2 0x10
//第二通道無功功率
#define PowerQ2 0x11
//通訊數據備份寄存器
#define BackupData 0x16
//通訊校驗和寄存器 2字節
#define COMChecksum 0x17
//校表參數校驗和寄存器
#define SUMChecksum 0x18
//EMU 狀態寄存器 1字節
#define EMUSR 0x19
//系統狀態寄存器 1字節
#define SYSSTA 0x1A
//芯片ID,默認值ATT7053B0
#define IDCode 0x1B
/*校表參數寄存器地址映射
小ARM菜菜
QQ:925295580
*/
//EMU 中斷使能寄存器
#define EMUIE 0x30
//EMU 中斷標志寄存器
#define EMUIF 0x31
//寫保護寄存器
#define WPREG 0x32
//軟件復位寄存器
#define SRSTREG 0x33
//EMU 配置寄存器
#define EMUCFG 0x40
//時鐘/更新頻率配置寄存器
#define FreqCFG 0x41
//EMU 模塊使能寄存器
#define ModuleEn 0x42
//ADC 開關寄存器
#define ANAEN 0x43
//IO 輸出配置寄存器
#define IOCFG 0x45
//通道1 的有功功率校正
#define GP1 0x50
//通道1 的無功功率校正
#define GQ1 0x51
//通道1 的視在功率校正
#define GS1 0x52
//通道2 的視在功率校正
#define GS2 0x54
//通道2 的視在功率校正
#define GS2 0x55
//通道2 的視在功率校正
#define GS2 0x56
//無功相位補償
#define QPhsCal 0x58
//ADC 通道增益選擇
#define ADCCON 0x59
//電流通道2 增益補償
#define I2Gain 0x5B
//電流通道1 的偏置校正
#define I1Off 0x5C
//電流通道2 的偏置校正
#define I2Off 0x5D
//電壓通道的偏置校正
#define UOff 0x5E
//起動功率設置
#define PQStart 0x5F
//輸出脈沖頻率設置
#define HFConst 0x61
//竊電閾值設置
#define CHK 0x62
//竊電檢測電流域值
#define IPTAMP 0x63
//通道1 有功功率偏執校正參數,為8bit 補碼
#define P1OFFSET 0x65
//通道2 有功功率偏執校正參數,為8bit 補碼
#define P2OFFSET 0x66
//通道1 無功功率偏執校正參數,為8bit 補碼
#define Q1OFFSET 0x67
//通道2 無功功率偏執校正參數,為8bit 補碼
#define Q2OFFSET 0x68
//通道1 有效值補償寄存器,為8bit 無符號數
#define I1RMSOFFSET 0x69
//通道2 有效值補償寄存器,為8bit 無符號數
#define I2RMSOFFSET 0x6A
//電流過零閾值設置寄存器
#define ZCrossCurrent 0x6C
//通道1 的相位校正(PQ 方式)
#define GPhs1 0x6D
//通道2 的相位校正(PQ 方式)
#define GPhs2 0x6E
//快速有功脈沖計數)
#define PFCnt 0x6F
//快速無功脈沖計數
#define QFCnt 0x70
//快速視在脈沖計數
#define SFCnt 0x71
#include <PL3201_Addr_Map.h>
extern void Erase_Write_State(uint8_t f);
extern uint8_t Read_At93c56(uint8_t addr);
extern void Write_At93c56(uint8_t addr,uint8_t dat);
sbit AT_CS=P2^2;
sbit SCLK=P1^5 ;
sbit SDI=P1^4;//sbit SDI=P1^6;
sbit SDO=P1^7;
sbit CS=P2^1;
//如有疑問請參閱王建華的PCB之終端板為依據
//2013年4月7日
//小ARM菜菜
extern void delay10us(void);
/*
寫入一個字節從指定的地址
*/
void Write_At93c56(uint8_t addr,uint8_t dat)
{
uint8_t i;
CS=1;
SCLK=0;
AT_CS=1;
SDI=1;
delay10us();
SCLK=1; //1
delay10us();
SCLK=0;
delay10us();
SDI=0;
delay10us();
SCLK=1; //0
delay10us();
SCLK=0;
delay10us();
SDI=1;
delay10us();
SCLK=1; //1
delay10us();
SCLK=0;
delay10us();
SCLK=1; //A8
delay10us();
SCLK=0;
delay10us();
for (i = 0; i < 8; i++) //地址
{
if (addr & 0x80)
SDI=1;
else
SDI=0;
addr <<= 1;
delay10us();
SCLK=1; //地址寫入高位在前
delay10us();
SCLK=0;
delay10us();
}
for (i = 0; i < 8; i++) //數據
{
if (dat & 0x80)
SDI=1;
else
SDI=0;
dat <<= 1;
delay10us();
SCLK=1; //地址寫入高位在前
delay10us();
SCLK=0;
delay10us();
}
//要延時或者檢測SDO的狀態,因為此時芯片處于忙碌狀態的話就會導致以后的數據寫入失敗,
//這個時間最大Twp=10MS
//詳情參考手冊
AT_CS=0;
delay10us();
// DrvSYS_Delay(1);//延時1ms
//Tcs=250ns-1000ns后拉高
AT_CS=1;
delay10us();
while(SDO==0);//芯片忙!
SCLK=0;
AT_CS=0;
}
/*
讀取一個字節從指定的地址
*/
uint8_t Read_At93c56(uint8_t addr)
{
uint8_t dat=0,i;
CS=1;
SCLK=0;
AT_CS=1;
delay10us();
SDI=1;
delay10us();
SCLK=1; //1
delay10us();
SCLK=0;
delay10us();
SDI=1;
delay10us();
SCLK=1; //1
delay10us();
SCLK=0;
delay10us();
SDI=0;
delay10us();
SCLK=1; //0
delay10us();
SCLK=0;
delay10us();
SCLK=1; //A8
delay10us();
SCLK=0;
delay10us();
for (i = 0; i < 8; i++)
{
if (addr & 0x80)
SDI=1;
else
SDI=0;
addr <<= 1;
delay10us();
SCLK=1; //地址寫入高位在前
delay10us();
SCLK=0;
delay10us();
}
for (i = 0; i < 8; i++)
{
SCLK=1;
dat<<=1;
if (SDO==1) //數據讀出
dat |= 0x01;
else
dat &= 0xfe;
delay10us();
SCLK=0;
delay10us();
}
SCLK=0;
AT_CS=0;
return dat;
}
/*
寫保護
F=1:開啟寫保護
F=0:關閉寫保護
*/
void Erase_Write_State(uint8_t f)
{
uint8_t i,da;
if(f>0)
{
da=0x00; //dis能
}
else
{
da=0xc0; //en禁能
}
CS=1;
SCLK=0;
AT_CS=1;
SDI=1;
delay10us();
SCLK=1; //1
delay10us();
SCLK=0;
delay10us();
SDI=0;
delay10us();
SCLK=1; //0
delay10us();
SCLK=0;
delay10us();
SDI=0;
delay10us();
SCLK=1; //0
delay10us();
SCLK=0;
delay10us();
//寫入命令0xc0
for (i = 0; i < 8; i++)
{
if (da & 0x80)
SDI=1;
else
SDI=0;
da <<= 1;
delay10us();
SCLK=1; //地址寫入高位在前
delay10us();
SCLK=0;
delay10us();
}
SCLK=1; //補足A8-A0
delay10us();
SCLK=0;
delay10us();
SCLK=0;
AT_CS=0;
}
#include "ATT7053BU_SPI.h"
sbit AT_CS=P2^2; //AT93C56
sbit SCLK=P1^5 ;
sbit SDI=P1^4;//sbit SDI=P1^6;
sbit SDO=P1^7;
sbit CS=P2^1;
//如有疑問請參閱王建華的PCB之終端板為依據
//2013年4月7日
//小ARM菜菜
void delay10us(void)
{
unsigned char a;
for(a=22;a>0;a--);
}
void ATT7035BU_Write(uint8_t addr,uint32_t dat)
{
unsigned char i,j;
uint8_t temp[3];
addr|=0x80; //寫所以要置高位為1
dat&=0x00ffffff; //強制首位字節為0,因為無效,只有24個比特,3個字節有效
temp[2] = dat; //低8為
dat>>=8 ;
temp[1] = dat; //中8為
dat>>=8 ;
temp[0] = dat; //高8為
SCLK=0;
CS=0;
AT_CS=0;//must be 0!
//寫命令
for (i = 0; i < 8; i++)
{
if (addr & 0x80)
SDI=1;
else
SDI=0;
addr <<= 1;
delay10us();
SCLK=1;
delay10us();
SCLK=0;
delay10us();
}
//寫應用數據,從高位開始
for(j=0;j<3;j++)
{
for (i = 0; i < 8; i++)
{
if (temp[j] & 0x80)
SDI=1;
else
SDI=0;
temp[j] <<= 1;
delay10us();
SCLK=1;
delay10us();
SCLK=0;
delay10us();
}
}
CS=1;
SCLK=1;
}
uint32_t ATT7035BU_Read(uint8_t addr)
{
unsigned char i,j;
uint32_t temp=0;
uint8_t dat;
addr&=0x7f;//高位強制為0.
SCLK=0;
CS=0;
AT_CS=0;//must be 0!
//寫ADDR
for (i = 0; i < 8; i++)
{
if (addr & 0x80)
SDI=1;
else
SDI=0;
addr <<= 1;
delay10us();
SCLK=1;
delay10us();
SCLK=0;
delay10us();
}
//讀取數據
for(j=0;j<3;j++)
{
for (i = 0; i < 8; i++)
{
if (dat & 0x80)
SDI=1;
else
SDI=0;
dat <<= 1;
delay10us();
SCLK=1;
delay10us();
if (SDO==1)
dat |= 0x01;
else
dat &= 0xfe;
SCLK=0;
delay10us();
}
temp|=dat ;//接收
temp<<=8; //next
// val= dat;//val[0]高位24,val[2]地位0,
}
CS=1;
SCLK=1;
return temp; //返回數據
}
#include <PL3201_Addr_Map.h>
#include "RTC.h"
void Write_RTC( uint8_t Year,uint8_t Month,uint8_t Day,uint8_t Hour,uint8_t Minute,uint8_t Second,uint8_t Week)
{
//關閉寫保護
EXT_ADR = Write_Protect_Register;
EXT_DAT = 0xff;
//日期
EXT_ADR = Year_Register;
EXT_DAT = Year;
EXT_ADR = Month_Register;
EXT_DAT = Month;
EXT_ADR = Day_Register;
EXT_DAT = Day;
EXT_ADR = Week_Register;
EXT_DAT = Week;
//時間
EXT_ADR = Hour_Register;
EXT_DAT = Hour;
EXT_ADR = Minute_Register;
EXT_DAT = Minute;
EXT_ADR = Second_Register;
EXT_DAT = Second;
//寫保護
EXT_ADR = Write_Protect_Register;
EXT_DAT = 0;
}
//讀取RTC數據
uint8_t Read_RTC_Data(uint8_t addr)
{
uint8_t temp=0;
EXT_ADR = addr;
temp=EXT_DAT;
return temp;
}