📄 lib.c
字号:
/**************************************************************************************************/
/* */
/* Copyright 2002 国家电力公司南京电力自动化设备总厂 */
/* */
/**************************************************************************************************/
/**************************************************************************************************/
/* */
/* 文件名 版 本 */
/* */
/* lib.c BHcpu-CPU-0.1 */
/* */
/* 概述 */
/* */
/* 公用驱动程序函数库。由下列几部分组成: */
/* EEPROM参数读写驱动程序 */
/* DS1306时钟芯片驱动程序 */
/* 数据进制转换程序 */
/* 其他驱动程序 */
/* */
/* 编程 */
/* */
/* 张金贵 */
/* */
/* */
/* 提供函数 */
/* */
/* */
/* */
/* 调用函数 */
/* */
/* 无 */
/* */
/* 头文件 */
/* */
/* nucleus.h Nucleus PLUS 操作系统函数说明 */
/* cpu32r.h CPU32的SIM、QSM、TPU各寄存器说明 */
/* */
/* 修改记录 */
/* */
/* 姓 名 日 期 说 明 */
/* */
/* 张金贵 2002.06.18 首次建立版本 0.1. */
/* */
/**************************************************************************************************/
#include "datalib.h"
#include "cpu32r.h"
#include "lib.h"
#include "smp.h"
extern uint8 KR_wdierr_buffer;
extern uint16 CLK_err;
extern uint16 SPI_work;
//--------------------------------------------------------------------------------------------------
void QSM_Initialize() //初始化CPU的QSM模块
{
register uint8 i;
*QSM_QMCR=0x008A; // QSM 寄存器在管理级空间,中断仲裁识别码为‘1010B’
*QSM_QILR=0x04; // QSPI中断级别为0,SCI中断级别为4‘00 000 100B’
*QSM_QIVR=0x50; // QSPI中断向量号为0x51(81),SCI中断向量号为0x50(80)
*QSM_QPDR=0xEB; // 预置QSM口数据
*QSM_QPAR=0x6B; // 设置管脚功能
*QSM_QDDR=0x7E; // 设置管脚方向 1:out 0:in
for (i=0;i<16;i++) // 清零 QSPI RAM
{
*(QSM_CmRAM+i)=0x00;
*(QSM_TxRAM+i)=0x00;
*(QSM_RxRAM+i)=0x00;
}
*QSM_SPCR1=0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0=0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2=0x0000; // 队列结束指针为0、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3=0x00; // 禁止反馈路径、中断、暂停
*QSM_SPSR =0; // QSPI标志清零
*QSM_SCCR0=65; // 设置SCI波特率9600
*QSM_SCCR1=0x102C; // 收、发允许,10位模式
SPI_work=0;
}
void Intdog_clear() // 清除内部看门狗
{
*SIM_SWSR=0x55;
*SIM_SWSR=0xAA;
}
void Extdog_clear() // 清除外部看门狗
{
uint8 static Wdi_H;
if(Wdi_H)
{
Wdi_H=0;
Bit_asn(&KR_wdierr_buffer,6,0); //正码缓冲0
Bit_asn(&KR_wdierr_buffer,0,1); //负码缓冲0
*KR_wdierr=KR_wdierr_buffer;
}
else
{
Wdi_H=1;
Bit_asn(&KR_wdierr_buffer,6,1); //正码缓冲0
Bit_asn(&KR_wdierr_buffer,0,0); //负码缓冲0
*KR_wdierr=KR_wdierr_buffer;
}
}
//--------------------------------------------------------------------------------------------------
void Eep_write_enable() // Eeprom允许写入
{
//20040618buby
SPI_work=0xff;
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_SPCR1=0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0=0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2=0x0000; // 队列结束指针为0、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3=0x00; // 禁止反馈路径、中断、暂停
*QSM_TxRAM=0x06; *QSM_CmRAM=0x3C; // 输出写允许命令 0x06
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
//20040618buby
SPI_work=0x00;
//*QSM_QPDR &= 0xEF;
}
void Eep_write_disable() // Eeprom禁止写入
{
//20040618buby
SPI_work=0xff;
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_SPCR1=0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0=0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2=0x0000; // 队列结束指针为0、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3=0x00; // 禁止反馈路径、中断、暂停
*QSM_TxRAM=0x04; *QSM_CmRAM=0x3C; // 输出写禁止命令 0x04
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
//20040618buby
SPI_work=0x00;
//*QSM_QPDR &= 0xEF;
}
uint8 Eep_read_status() // Eeprom状态读取
{
//20040618buby
SPI_work=0xff;
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_SPCR1=0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0=0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2=0x0100; // 队列结束指针为1、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3=0x00; // 禁止反馈路径、中断、暂停
*(QSM_TxRAM+0)=0x05; *(QSM_CmRAM+0)=0xBC; // 输出读状态命令 0x05
*(QSM_TxRAM+1)=0x00; *(QSM_CmRAM+1)=0x3C; // 读入状态
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
//*QSM_QPDR &= 0xEF;
//20040618buby
SPI_work=0x00;
return (*(QSM_RxRAM+1)); // 返回状态
}
uint8 Eep_read_one(uint16 addr) // Eeprom读取一字节
{
//20040618buby
SPI_work=0xff;
//
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_SPCR1=0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0=0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2=0x0300; // 队列结束指针为3、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3=0x00; // 禁止反馈路径、中断、暂停
*(QSM_TxRAM+0)=0x03; *(QSM_CmRAM+0)=0xBC; // 输出读数据命令 0x03
*(QSM_TxRAM+1)=addr/256; *(QSM_CmRAM+1)=0xBC; // 输出数据地址高八位
*(QSM_TxRAM+2)=addr%256; *(QSM_CmRAM+2)=0xBC; // 输出数据地址地八字
*(QSM_TxRAM+3)=0; *(QSM_CmRAM+3)=0x3C; // 读入数据字节
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
//*QSM_QPDR &= 0xEF;
//20040618buby
SPI_work=0x00;
return (*(QSM_RxRAM+3)); // 返回读入数据字节
}
uint16 Eep_read_two(uint16 addr) // Eeprom读取一字
{
//20040618buby
SPI_work=0xff;
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_SPCR1=0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0=0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2=0x0400; // 队列结束指针为4、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3=0x00; // 禁止反馈路径、中断、暂停
*(QSM_TxRAM+0)=0x03; *(QSM_CmRAM+0)=0xBC; // 输出读数据命令 0x03
*(QSM_TxRAM+1)=addr/256; *(QSM_CmRAM+1)=0xBC; // 输出数据地址高八位
*(QSM_TxRAM+2)=addr%256; *(QSM_CmRAM+2)=0xBC; // 输出数据地址低八字
*(QSM_TxRAM+3)=0; *(QSM_CmRAM+3)=0xBC; // 读入数据高字节
*(QSM_TxRAM+4)=0; *(QSM_CmRAM+4)=0x3C; // 读入数据低字节
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
//*QSM_QPDR &= 0xEF;
//20040618buby
SPI_work=0x00;
return (*(QSM_RxRAM+3))*256 + (*(QSM_RxRAM+4)); // 返回读入数据字
}
void Eep_write_one(uint16 addr,uint8 data) // Eeprom写入一字节
{
uint8 sts;
//20040618buby
SPI_work=0xff;
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_SPCR1=0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0=0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2=0x0300; // 队列结束指针为4、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3=0x00; // 禁止反馈路径、中断、暂停
*(QSM_TxRAM+0)=0x02; *(QSM_CmRAM+0)=0xBC; // 输出写数据命令 0x02
*(QSM_TxRAM+1)=addr/256; *(QSM_CmRAM+1)=0xBC; // 输出数据地址高八位
*(QSM_TxRAM+2)=addr%256; *(QSM_CmRAM+2)=0xBC; // 输出数据地址地八字
*(QSM_TxRAM+3)=data; *(QSM_CmRAM+3)=0x3C; // 写入数据字节
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
//*QSM_QPDR &= 0xEF;
do sts = Eep_read_status(); while (sts&0x01); // 等待写入完成
//20040618buby
SPI_work=0x00;
}
void Eep_write_two(uint16 addr,uint16 data) // Eeprom写入一字
{
uint8 sts;
//20040618buby
SPI_work=0xff;
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_SPCR1=0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0=0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2=0x0400; // 队列结束指针为4、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3=0x00; // 禁止反馈路径、中断、暂停
*(QSM_TxRAM+0)=0x02; *(QSM_CmRAM+0)=0xBC; // 输出写数据命令 0x02
*(QSM_TxRAM+1)=addr/256; *(QSM_CmRAM+1)=0xBC; // 输出数据地址高八位
*(QSM_TxRAM+2)=addr%256; *(QSM_CmRAM+2)=0xBC; // 输出数据地址地八字
*(QSM_TxRAM+3)=data/256; *(QSM_CmRAM+3)=0xBC; // 写入数据字节
*(QSM_TxRAM+4)=data%256; *(QSM_CmRAM+4)=0x3C; // 写入数据字节
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
do sts = Eep_read_status(); while (sts&0x01); // 等待写入完成
//20040618buby
SPI_work=0x00;
//*QSM_QPDR &= 0xEF;
}
void Extdog_on() // 打开外部看门狗
{
uint8 sts;
Eep_write_enable();
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_SPCR1=0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0=0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2=0x0100; // 队列结束指针为1、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3=0x00; // 禁止反馈路径、中断、暂停
*(QSM_TxRAM+0)=0x01; *(QSM_CmRAM+0)=0xBC; // 输出写状态命令 0x02
*(QSM_TxRAM+1)=0x0C; *(QSM_CmRAM+1)=0x3C; // 开Watch dog,BLOCK EEPROM
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
do sts = Eep_read_status(); while (sts&0x01); // 等待写入完成
Eep_write_disable();
//*QSM_QPDR &= 0xEF;
}
void Extdog_off() // 关闭外部看门狗
{
uint8 sts;
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_SPCR1=0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0=0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2=0x0100; // 队列结束指针为1、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3=0x00; // 禁止反馈路径、中断、暂停
*(QSM_TxRAM+0)=0x01; *(QSM_CmRAM+0)=0xBC; // 输出写状态命令 0x02
*(QSM_TxRAM+1)=0x30; *(QSM_CmRAM+1)=0x3C; // 关Watch dog
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
do sts = Eep_read_status(); while (sts&0x01); // 等待写入完成
//*QSM_QPDR &= 0xEF;
}
//--------------------------------------------------------------------------------------------------
void Write_DS1306_enable() // DS1306允许写命令
{
uint8 sts;
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_QPDR |= 0x10; // 使DS1306的片选PCS1输出高电平有效
*QSM_SPCR1 = 0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0 = 0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2 = 0x0100; // 队列结束指针为1、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3 = 0x00; // 禁止反馈路径、中断、暂停
*(QSM_TxRAM+0)=0x8F; *(QSM_CmRAM+0)=0xBf; // 输出地址字节
*(QSM_TxRAM+1)=0x00; *(QSM_CmRAM+1)=0x3f; // 输出命令字节
// *(QSM_TxRAM+1)=0x01; *(QSM_CmRAM+1)=0x3f; // 输出命令字节
// *(QSM_TxRAM+0)=0x8F; *(QSM_CmRAM+0)=0xB3; // 输出地址字节
// *(QSM_TxRAM+1)=0x01; *(QSM_CmRAM+1)=0x33; // 输出命令字节
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
*QSM_QPDR &= 0xEF; // 使DS1306的片选PCS1输出低电平无效
for (sts=0;sts<100;sts++);
}
void Write_DS1306_disable() // DS1306禁止写命令
{
uint8 sts;
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_QPDR |= 0x10; // 使DS1306的片选PCS1输出高电平有效
*QSM_SPCR1 = 0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0 = 0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2 = 0x0100; // 队列结束指针为1、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3 = 0x00; // 禁止反馈路径、中断、暂停
*(QSM_TxRAM+0)=0x8F; *(QSM_CmRAM+0)=0xBf; // 输出地址字节
*(QSM_TxRAM+1)=0x40; *(QSM_CmRAM+1)=0x3f; // 输出命令字节
// *(QSM_TxRAM+0)=0x8F; *(QSM_CmRAM+0)=0xB3; // 输出地址字节
// *(QSM_TxRAM+1)=0x41; *(QSM_CmRAM+1)=0x33; // 输出命令字节
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
*QSM_QPDR &= 0xEF; // 使DS1306的片选PCS1输出低电平无效
for (sts=0;sts<100;sts++);
}
uint8 Read_DS1306(uint8 adr) // 从DS1306读一字节
{
uint8 sts;
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_QPDR |= 0x10; // 使DS1306的片选PCS1输出高电平有效
*QSM_SPCR1 = 0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0 = 0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2 = 0x0100; // 队列结束指针为1、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3 = 0x00; // 禁止反馈路径、中断、暂停
*(QSM_TxRAM+0)=adr; *(QSM_CmRAM+0)=0xBf; // 输出时钟地址字节
*(QSM_TxRAM+1)=000; *(QSM_CmRAM+1)=0x3f; // 读入时钟数据字节
// *(QSM_TxRAM+0)=adr; *(QSM_CmRAM+0)=0xB3; // 输出时钟地址字节
// *(QSM_TxRAM+1)=000; *(QSM_CmRAM+1)=0x33; // 读入时钟数据字节
*QSM_SPCR1=0x9407; // QSPI允许
while ((*QSM_SPSR&0x80)==00); // 等待传输完成
// for (sts=0;sts<20;sts++);
*QSM_QPDR &= 0xEF; // 使DS1306的片选PCS1输出低电平无效
return (*(QSM_RxRAM+1)); // 返回读入数据字节
}
void Write_DS1306(uint8 adr,uint8 dat) // 向DS1306写一字节
{
uint8 sts;
// Write_DS1306_enable(); // DS1306允许写命令
// for (sts=0;sts<50;sts++);
asm (" MOVE.B $FFFC1F,D1"); // QSPI标志清零
asm (" MOVE.B #0,$FFFC1F");
*QSM_QPDR |= 0x10; // 使DS1306的片选PCS1输出高电平有效
*QSM_SPCR1 = 0x1407; // QSPI禁止、SCK之前延时20、SCK之后延时7
*QSM_SPCR0 = 0xA109; // QSPI主机方式、每次传送8位、速率 1Mbps
*QSM_SPCR2 = 0x0100; // 队列结束指针为1、队列开始指针为0,禁止中断、环绕
*QSM_SPCR3 = 0x00; // 禁止反馈路径、中断、暂停
*(QSM_TxRAM+0)=adr; *(QSM_CmRAM+0)=0xBf; // 输出时钟地址字节
*(QSM_TxRAM+1)=dat; *(QSM_CmRAM+1)=0x3f; // 输出时钟数据字节
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -