芯片:FT60E12X FT60F12X
芯片规格书以及参考demo
芯片规格书可以了解到MCU的详细情况,包括架构、外设的配置方法、寄存器等情况
通过参考官方的demo程序则能够快速的了解MCU的编程方法,并展开后续的开发工作
硬件准备
一块带FT60E12X的板子 以及对应的原理图
环境搭建IDE
跑通一个简单demo
示例代码
IR_SEND
// Project: FT60E12x_IR_SEND.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 演示程序中,IR红外是采用6122协议,起始信号是9ms低电平,到4.5ms高电平,再到低8位用户识别码,到高8位的用户识别码,8位数据码,8位数据码的反码。SendIO(PA4)定时(5秒钟)发送一次,接收端收到遥控器发过来的数据后,校验数据互为补码,LED会开关。
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//********************************************************
#include "SYSCFG.h"
//**********************宏定义****************************
#define uchar unsigned char
#define uint unsigned int
#define IRSendIO PA4 // 串口的发送脚
#define IRSend_HIGH_1 1 // 560uS
#define IRSend_LOW_1 3 // 1680uS
#define IRSend_HIGH_0 1 // 560uS
#define IRSend_LOW_0 1 // 560uS
#define IRSend_PIN_1 T0IE = 1 // 发送数据 开启定时器0
#define IRSend_PIN_0 T0IE = 0 // 关闭定时器0
#define Status_NOSend 0 // 不发送的状态
#define Status_Head 1 // 发送引导码的状态
#define Status_Data 2 // 发送数据的状态
uchar IRSendStatus; // 发送状态,是发送引导码还是数据
uchar IRSendData; // 发送的数据中转变量
uchar TxBit=0,TxTime=0;
uchar SendBit = 0;
uchar level0,level1; // 一位数据里发送与关闭的时间值
bit SendLastBit = 0;
uchar SaveLastBit = 0;
uint SYSTime5S = 0; // 系统时间,5S发送一次
uchar IRData[4] = {0x00,0xff,0x40,0xBf}; // 需要发送的4个数据
/*----------------------------------------------------
* 函数名:POWER_INITIAL
* 说明:初始化单片机
* 输入:无
* 输出:无
----------------------------------------------------*/
void POWER_INITIAL(void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
//Bit0=1,系统时钟为内部振荡器
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B11101111; //PA输入输出 0-输出 1-输入
//PA4->输出
PORTC = 0B00000000;
TRISC = 0B11111111; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
WPUC = 0B00000000; //PC端口上拉控制 1-开上拉 0-关上拉
//60系列PC口无上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 0:睡眠时停止工作:1: 睡眠时保持工作。当T2时钟不是选择指令时钟的时候
}
/*----------------------------------------------------
* 函数名:TIMER0_INITIAL
* 功能: 初始化设置定时器v
* 说明: 38KHz发生器,1000000/38000=26.3uS .由于定时太短,频繁进定时器,时间有一定的
* 误差,239并不是直接算出来的, 是示波器看的。
* 设置TMR0定时时长=(1/系统时钟频率)*指令周期*预分频值*26
* =(1/16000000)*4*2*26=13us
----------------------------------------------------*/
void TIMER0_INITIAL (void)
{
OPTION = 0B00000000;
//Bit5 T0CS Timer0时钟源选择
//1-外部引脚电平变化T0CKI 0-内部时钟(FOSC/2)
//Bit4 T0CKI引脚触发方式 1-下降沿 0-上升沿
//Bit3 PSA 预分频器分配位 0-Timer0 1-WDT
//Bit2:0 PS 8个预分频比 000 - 1:2
TMR0 = 239;
T0IF = 0; //清空T0软件中断
}
/*----------------------------------------------------
* 函数名:TIMER2_INITIAL
* 功能: 初始化设置定时器2 配置成PWM
* 设置: TMR2输出比较值定时=(1/系统时钟频率)*4*预分频值*后分频值*PR2
* =(1/16000000)*4*4*4*141
* =564us
----------------------------------------------------*/
void Timer2Inital(void)
{
T2CON0 = 0B00011001; //T2预分频1:4,后分频1:4
//Bit[7:0]: 无意义; 1:把PR2/P1xDTy缓冲值分别更新到PR2寄存器和P1xDTy_ACT
//Bit[6:3]: 定时器2输出后分频比选择 0000: 1:1;0001: 1:2;……1:16
//Bit[2:0]: 关闭定时器2;1:打开定时器2
//Bit[1:0]: 定时器2预分频选择 00:1;01:4;1x:16
T2CON1 = 0B00000000; //T2时钟来自系统时钟,PWM1连续模式
//Bit4: PWM模式选择
// 0:连续模式;1:单脉冲模式
//Bit3: 0:PWM模式;1:蜂鸣器模式
//Bit[2:0] Timer2时钟源选择
// 000:指令时钟;
// 001:系统时钟;
// 010:HIRC的2倍频;
// 100:HIRC;
// 101:LIRC
TMR2H = 0; //定时器2计数寄存器
TMR2L = 141;
PR2H = 0; //周期=(PR+1)*Tt2ck*TMR2预分频(蜂鸣器模式周期*2)
PR2L = 141;
P1ADTH = 0; //脉宽=P1xDT*Tt2ck*TMR2预分频(蜂鸣器模式没用到)
P1ADTL = 50;
P1OE = 0B00000000; //充许P1A0输出PWM(配置成timer定时器时这位清零)
//Bit7: 0:禁止P1C输出到管脚;1:充许P1C输出到管脚
//Bit6: 0:禁止P1B输出到管脚;1:充许P1B输出到管脚
//Bit[5:0]: 0:禁止P1Ax输出到管脚;1:充许P1Ax输出到管脚
P1POL = 0B00000000; //高电平有效
//Bit7: 0:P1C高电平有效;1:P1C低电平有效
//Bit6: 0:P1B高电平有效;1:P1B低电平有效
//Bit[5:0]: 0:P1Ax高电平有效;1:P1Ax低电平有效
P1CON = 0B00000000;
//Bit7: PWM1 重启使能位
// 1 = 故障刹车时,P1BEVT位在退出关闭事件时自动清零,PWM1自动重启
// 0 = 故障刹车时,必须用软件将P1BEVT清零以重启PWM1
//Bit[6:0]: PWM1死区时间设置
// P1DCn = 预定MPWM信号应转变为有效与PWM信号实际转为有效之间的T2CK周期数
MSCON = 0B00110000; //Bit0: 0:T2睡眠时停止工作
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 0:睡眠时停止工作:1: 睡眠时保持工作。当T2时钟不是选择指令时钟的时候
TMR2IF = 0; //清TMER2中断标志
TMR2IE = 1; //使能TMER2的中断(配置成timer定时器时不注释)
TMR2ON = 1; //使能TMER2启动
PEIE = 1; //使能外设中断
GIE = 1; //使能全局中断
}
/*-------------------------------------------------
* 函数名:SendCtrl
* 功能: 发送数据函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void SendCtrl(void)
{
if (IRSendStatus == Status_NOSend) // 不发送的状态
{
IRSend_PIN_0;
SendBit = 0;
TxTime = 0;
}
else if (IRSendStatus == Status_Head) // 发送引导码
{
TxTime++;
if (TxTime < 17) // 发送9mS信号
{
IRSend_PIN_1;
}
else if (TxTime < 24) // 4.5mS不发送
{
IRSend_PIN_0;
}
else
{
TxTime = 0;
IRSendStatus = Status_Data;
}
IRSendData = IRData[0];
TxBit = 0x01;
}
else if(IRSendStatus == Status_Data) // 发送数据
{
if (IRSendData & TxBit) // 1,是1:3的时间
{
level1 = IRSend_HIGH_1;
level0 = IRSend_LOW_1;
}
else // 0,是1:1的时间
{
level1 = IRSend_HIGH_0;
level0 = IRSend_LOW_0;
}
TxTime++;
if (TxTime <= level1) // 发送信号
{
IRSend_PIN_1;
}
else if (TxTime <= (level0+level1)) // 不发送信号
{
IRSend_PIN_0;
}
else if (SendBit < 4) // 发送4位数据未完成
{
TxTime = 1;
IRSend_PIN_1;
SaveLastBit = IRSendData & TxBit;
TxBit <<= 1;
if (TxBit == 0x00) // 发送完一个字节
{
TxBit = 0x01;
SendBit++;
IRSendData = IRData[SendBit];
if (SendBit > 3) // 最后一位要注意,因为发送完了还要有一个脉冲
{
SendLastBit = 1;
}
}
}
else // 数据完成了,要补脉冲
{
if(SendLastBit)
{
TxTime++;
if(SaveLastBit)
{
if(TxTime < 3)
{
IRSend_PIN_0;
}
else if(TxTime < 4)
{
IRSend_PIN_1;
}
else
{
IRSend_PIN_0;
IRSendStatus = Status_NOSend;
IRSend_PIN_0;
SendLastBit = 0;
TxBit = 0;
TxTime = 0;
}
}
else
{
if(TxTime < 5)
{
IRSend_PIN_0;
}
else if(TxTime < 6)
{
IRSend_PIN_1;
}
else
{
IRSend_PIN_0;
IRSendStatus = Status_NOSend;
IRSend_PIN_0;
SendLastBit = 0;
TxBit = 0;
TxTime = 0;
}
}
}
}
}
}
/*-------------------------------------------------
* 函数名:interrupt ISR
* 功能: 中断处理,包括定时器0中断和外部中断
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void interrupt ISR(void)
{
//定时器0的中断处理
if(T0IE && T0IF) //13us
{
TMR0 = 239; //注意:对TMR0重新赋值TMR0在两个周期内不变化
T0IF = 0;
IRSendIO = ~IRSendIO; //翻转电平 产生38KHz信号
}
//定时器2的中断处理
if(TMR2IE && TMR2IF) //560us中断一次 红外每一位都是560uS的倍数
{
TMR2IF = 0;
SendCtrl();
SYSTime5S++;
//IRSendIO = ~IRSendIO;
}
}
/*-------------------------------------------------
* 函数名:main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main(void)
{
POWER_INITIAL();
TIMER0_INITIAL();
Timer2Inital();
GIE = 1; //开中断
while(1)
{
if(SYSTime5S >10000) //每隔5S发射一次
{
SYSTime5S = 0;
IRSendStatus = Status_Head;
}
}
}
IR_RECEIVE
// Project: FT60E12x_IR_SEND.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 演示程序中,IR红外是采用6122协议,起始信号是9ms低电平,到4.5ms高电平,再到低8位用户识别码,到高8位的用户识别码,8位数据码,8位数据码的反码。SendIO(PA4)定时(5秒钟)发送一次,接收端收到遥控器发过来的数据后,校验数据互为补码,LED会开关。
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//********************************************************
#include "SYSCFG.h"
//**********************宏定义****************************
#define uchar unsigned char
#define uint unsigned int
#define IRSendIO PA4 // 串口的发送脚
#define IRSend_HIGH_1 1 // 560uS
#define IRSend_LOW_1 3 // 1680uS
#define IRSend_HIGH_0 1 // 560uS
#define IRSend_LOW_0 1 // 560uS
#define IRSend_PIN_1 T0IE = 1 // 发送数据 开启定时器0
#define IRSend_PIN_0 T0IE = 0 // 关闭定时器0
#define Status_NOSend 0 // 不发送的状态
#define Status_Head 1 // 发送引导码的状态
#define Status_Data 2 // 发送数据的状态
uchar IRSendStatus; // 发送状态,是发送引导码还是数据
uchar IRSendData; // 发送的数据中转变量
uchar TxBit=0,TxTime=0;
uchar SendBit = 0;
uchar level0,level1; // 一位数据里发送与关闭的时间值
bit SendLastBit = 0;
uchar SaveLastBit = 0;
uint SYSTime5S = 0; // 系统时间,5S发送一次
uchar IRData[4] = {0x00,0xff,0x40,0xBf}; // 需要发送的4个数据
/*----------------------------------------------------
* 函数名:POWER_INITIAL
* 说明:初始化单片机
* 输入:无
* 输出:无
----------------------------------------------------*/
void POWER_INITIAL(void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
//Bit0=1,系统时钟为内部振荡器
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B11101111; //PA输入输出 0-输出 1-输入
//PA4->输出
PORTC = 0B00000000;
TRISC = 0B11111111; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
WPUC = 0B00000000; //PC端口上拉控制 1-开上拉 0-关上拉
//60系列PC口无上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 0:睡眠时停止工作:1: 睡眠时保持工作。当T2时钟不是选择指令时钟的时候
}
/*----------------------------------------------------
* 函数名:TIMER0_INITIAL
* 功能: 初始化设置定时器v
* 说明: 38KHz发生器,1000000/38000=26.3uS .由于定时太短,频繁进定时器,时间有一定的
* 误差,239并不是直接算出来的, 是示波器看的。
* 设置TMR0定时时长=(1/系统时钟频率)*指令周期*预分频值*26
* =(1/16000000)*4*2*26=13us
----------------------------------------------------*/
void TIMER0_INITIAL (void)
{
OPTION = 0B00000000;
//Bit5 T0CS Timer0时钟源选择
//1-外部引脚电平变化T0CKI 0-内部时钟(FOSC/2)
//Bit4 T0CKI引脚触发方式 1-下降沿 0-上升沿
//Bit3 PSA 预分频器分配位 0-Timer0 1-WDT
//Bit2:0 PS 8个预分频比 000 - 1:2
TMR0 = 239;
T0IF = 0; //清空T0软件中断
}
/*----------------------------------------------------
* 函数名:TIMER2_INITIAL
* 功能: 初始化设置定时器2 配置成PWM
* 设置: TMR2输出比较值定时=(1/系统时钟频率)*4*预分频值*后分频值*PR2
* =(1/16000000)*4*4*4*141
* =564us
----------------------------------------------------*/
void Timer2Inital(void)
{
T2CON0 = 0B00011001; //T2预分频1:4,后分频1:4
//Bit[7:0]: 无意义; 1:把PR2/P1xDTy缓冲值分别更新到PR2寄存器和P1xDTy_ACT
//Bit[6:3]: 定时器2输出后分频比选择 0000: 1:1;0001: 1:2;……1:16
//Bit[2:0]: 关闭定时器2;1:打开定时器2
//Bit[1:0]: 定时器2预分频选择 00:1;01:4;1x:16
T2CON1 = 0B00000000; //T2时钟来自系统时钟,PWM1连续模式
//Bit4: PWM模式选择
// 0:连续模式;1:单脉冲模式
//Bit3: 0:PWM模式;1:蜂鸣器模式
//Bit[2:0] Timer2时钟源选择
// 000:指令时钟;
// 001:系统时钟;
// 010:HIRC的2倍频;
// 100:HIRC;
// 101:LIRC
TMR2H = 0; //定时器2计数寄存器
TMR2L = 141;
PR2H = 0; //周期=(PR+1)*Tt2ck*TMR2预分频(蜂鸣器模式周期*2)
PR2L = 141;
P1ADTH = 0; //脉宽=P1xDT*Tt2ck*TMR2预分频(蜂鸣器模式没用到)
P1ADTL = 50;
P1OE = 0B00000000; //充许P1A0输出PWM(配置成timer定时器时这位清零)
//Bit7: 0:禁止P1C输出到管脚;1:充许P1C输出到管脚
//Bit6: 0:禁止P1B输出到管脚;1:充许P1B输出到管脚
//Bit[5:0]: 0:禁止P1Ax输出到管脚;1:充许P1Ax输出到管脚
P1POL = 0B00000000; //高电平有效
//Bit7: 0:P1C高电平有效;1:P1C低电平有效
//Bit6: 0:P1B高电平有效;1:P1B低电平有效
//Bit[5:0]: 0:P1Ax高电平有效;1:P1Ax低电平有效
P1CON = 0B00000000;
//Bit7: PWM1 重启使能位
// 1 = 故障刹车时,P1BEVT位在退出关闭事件时自动清零,PWM1自动重启
// 0 = 故障刹车时,必须用软件将P1BEVT清零以重启PWM1
//Bit[6:0]: PWM1死区时间设置
// P1DCn = 预定MPWM信号应转变为有效与PWM信号实际转为有效之间的T2CK周期数
MSCON = 0B00110000; //Bit0: 0:T2睡眠时停止工作
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 0:睡眠时停止工作:1: 睡眠时保持工作。当T2时钟不是选择指令时钟的时候
TMR2IF = 0; //清TMER2中断标志
TMR2IE = 1; //使能TMER2的中断(配置成timer定时器时不注释)
TMR2ON = 1; //使能TMER2启动
PEIE = 1; //使能外设中断
GIE = 1; //使能全局中断
}
/*-------------------------------------------------
* 函数名:SendCtrl
* 功能: 发送数据函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void SendCtrl(void)
{
if (IRSendStatus == Status_NOSend) // 不发送的状态
{
IRSend_PIN_0;
SendBit = 0;
TxTime = 0;
}
else if (IRSendStatus == Status_Head) // 发送引导码
{
TxTime++;
if (TxTime < 17) // 发送9mS信号
{
IRSend_PIN_1;
}
else if (TxTime < 24) // 4.5mS不发送
{
IRSend_PIN_0;
}
else
{
TxTime = 0;
IRSendStatus = Status_Data;
}
IRSendData = IRData[0];
TxBit = 0x01;
}
else if(IRSendStatus == Status_Data) // 发送数据
{
if (IRSendData & TxBit) // 1,是1:3的时间
{
level1 = IRSend_HIGH_1;
level0 = IRSend_LOW_1;
}
else // 0,是1:1的时间
{
level1 = IRSend_HIGH_0;
level0 = IRSend_LOW_0;
}
TxTime++;
if (TxTime <= level1) // 发送信号
{
IRSend_PIN_1;
}
else if (TxTime <= (level0+level1)) // 不发送信号
{
IRSend_PIN_0;
}
else if (SendBit < 4) // 发送4位数据未完成
{
TxTime = 1;
IRSend_PIN_1;
SaveLastBit = IRSendData & TxBit;
TxBit <<= 1;
if (TxBit == 0x00) // 发送完一个字节
{
TxBit = 0x01;
SendBit++;
IRSendData = IRData[SendBit];
if (SendBit > 3) // 最后一位要注意,因为发送完了还要有一个脉冲
{
SendLastBit = 1;
}
}
}
else // 数据完成了,要补脉冲
{
if(SendLastBit)
{
TxTime++;
if(SaveLastBit)
{
if(TxTime < 3)
{
IRSend_PIN_0;
}
else if(TxTime < 4)
{
IRSend_PIN_1;
}
else
{
IRSend_PIN_0;
IRSendStatus = Status_NOSend;
IRSend_PIN_0;
SendLastBit = 0;
TxBit = 0;
TxTime = 0;
}
}
else
{
if(TxTime < 5)
{
IRSend_PIN_0;
}
else if(TxTime < 6)
{
IRSend_PIN_1;
}
else
{
IRSend_PIN_0;
IRSendStatus = Status_NOSend;
IRSend_PIN_0;
SendLastBit = 0;
TxBit = 0;
TxTime = 0;
}
}
}
}
}
}
/*-------------------------------------------------
* 函数名:interrupt ISR
* 功能: 中断处理,包括定时器0中断和外部中断
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void interrupt ISR(void)
{
//定时器0的中断处理
if(T0IE && T0IF) //13us
{
TMR0 = 239; //注意:对TMR0重新赋值TMR0在两个周期内不变化
T0IF = 0;
IRSendIO = ~IRSendIO; //翻转电平 产生38KHz信号
}
//定时器2的中断处理
if(TMR2IE && TMR2IF) //560us中断一次 红外每一位都是560uS的倍数
{
TMR2IF = 0;
SendCtrl();
SYSTime5S++;
//IRSendIO = ~IRSendIO;
}
}
/*-------------------------------------------------
* 函数名:main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main(void)
{
POWER_INITIAL();
TIMER0_INITIAL();
Timer2Inital();
GIE = 1; //开中断
while(1)
{
if(SYSTime5S >10000) //每隔5S发射一次
{
SYSTime5S = 0;
IRSendStatus = Status_Head;
}
}
}
IO
// Project: FT60E12x_IR_SEND.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 演示程序中,IR红外是采用6122协议,起始信号是9ms低电平,到4.5ms高电平,再到低8位用户识别码,到高8位的用户识别码,8位数据码,8位数据码的反码。SendIO(PA4)定时(5秒钟)发送一次,接收端收到遥控器发过来的数据后,校验数据互为补码,LED会开关。
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//********************************************************
#include "SYSCFG.h"
//**********************宏定义****************************
#define uchar unsigned char
#define uint unsigned int
#define IRSendIO PA4 // 串口的发送脚
#define IRSend_HIGH_1 1 // 560uS
#define IRSend_LOW_1 3 // 1680uS
#define IRSend_HIGH_0 1 // 560uS
#define IRSend_LOW_0 1 // 560uS
#define IRSend_PIN_1 T0IE = 1 // 发送数据 开启定时器0
#define IRSend_PIN_0 T0IE = 0 // 关闭定时器0
#define Status_NOSend 0 // 不发送的状态
#define Status_Head 1 // 发送引导码的状态
#define Status_Data 2 // 发送数据的状态
uchar IRSendStatus; // 发送状态,是发送引导码还是数据
uchar IRSendData; // 发送的数据中转变量
uchar TxBit=0,TxTime=0;
uchar SendBit = 0;
uchar level0,level1; // 一位数据里发送与关闭的时间值
bit SendLastBit = 0;
uchar SaveLastBit = 0;
uint SYSTime5S = 0; // 系统时间,5S发送一次
uchar IRData[4] = {0x00,0xff,0x40,0xBf}; // 需要发送的4个数据
/*----------------------------------------------------
* 函数名:POWER_INITIAL
* 说明:初始化单片机
* 输入:无
* 输出:无
----------------------------------------------------*/
void POWER_INITIAL(void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
//Bit0=1,系统时钟为内部振荡器
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B11101111; //PA输入输出 0-输出 1-输入
//PA4->输出
PORTC = 0B00000000;
TRISC = 0B11111111; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
WPUC = 0B00000000; //PC端口上拉控制 1-开上拉 0-关上拉
//60系列PC口无上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 0:睡眠时停止工作:1: 睡眠时保持工作。当T2时钟不是选择指令时钟的时候
}
/*----------------------------------------------------
* 函数名:TIMER0_INITIAL
* 功能: 初始化设置定时器v
* 说明: 38KHz发生器,1000000/38000=26.3uS .由于定时太短,频繁进定时器,时间有一定的
* 误差,239并不是直接算出来的, 是示波器看的。
* 设置TMR0定时时长=(1/系统时钟频率)*指令周期*预分频值*26
* =(1/16000000)*4*2*26=13us
----------------------------------------------------*/
void TIMER0_INITIAL (void)
{
OPTION = 0B00000000;
//Bit5 T0CS Timer0时钟源选择
//1-外部引脚电平变化T0CKI 0-内部时钟(FOSC/2)
//Bit4 T0CKI引脚触发方式 1-下降沿 0-上升沿
//Bit3 PSA 预分频器分配位 0-Timer0 1-WDT
//Bit2:0 PS 8个预分频比 000 - 1:2
TMR0 = 239;
T0IF = 0; //清空T0软件中断
}
/*----------------------------------------------------
* 函数名:TIMER2_INITIAL
* 功能: 初始化设置定时器2 配置成PWM
* 设置: TMR2输出比较值定时=(1/系统时钟频率)*4*预分频值*后分频值*PR2
* =(1/16000000)*4*4*4*141
* =564us
----------------------------------------------------*/
void Timer2Inital(void)
{
T2CON0 = 0B00011001; //T2预分频1:4,后分频1:4
//Bit[7:0]: 无意义; 1:把PR2/P1xDTy缓冲值分别更新到PR2寄存器和P1xDTy_ACT
//Bit[6:3]: 定时器2输出后分频比选择 0000: 1:1;0001: 1:2;……1:16
//Bit[2:0]: 关闭定时器2;1:打开定时器2
//Bit[1:0]: 定时器2预分频选择 00:1;01:4;1x:16
T2CON1 = 0B00000000; //T2时钟来自系统时钟,PWM1连续模式
//Bit4: PWM模式选择
// 0:连续模式;1:单脉冲模式
//Bit3: 0:PWM模式;1:蜂鸣器模式
//Bit[2:0] Timer2时钟源选择
// 000:指令时钟;
// 001:系统时钟;
// 010:HIRC的2倍频;
// 100:HIRC;
// 101:LIRC
TMR2H = 0; //定时器2计数寄存器
TMR2L = 141;
PR2H = 0; //周期=(PR+1)*Tt2ck*TMR2预分频(蜂鸣器模式周期*2)
PR2L = 141;
P1ADTH = 0; //脉宽=P1xDT*Tt2ck*TMR2预分频(蜂鸣器模式没用到)
P1ADTL = 50;
P1OE = 0B00000000; //充许P1A0输出PWM(配置成timer定时器时这位清零)
//Bit7: 0:禁止P1C输出到管脚;1:充许P1C输出到管脚
//Bit6: 0:禁止P1B输出到管脚;1:充许P1B输出到管脚
//Bit[5:0]: 0:禁止P1Ax输出到管脚;1:充许P1Ax输出到管脚
P1POL = 0B00000000; //高电平有效
//Bit7: 0:P1C高电平有效;1:P1C低电平有效
//Bit6: 0:P1B高电平有效;1:P1B低电平有效
//Bit[5:0]: 0:P1Ax高电平有效;1:P1Ax低电平有效
P1CON = 0B00000000;
//Bit7: PWM1 重启使能位
// 1 = 故障刹车时,P1BEVT位在退出关闭事件时自动清零,PWM1自动重启
// 0 = 故障刹车时,必须用软件将P1BEVT清零以重启PWM1
//Bit[6:0]: PWM1死区时间设置
// P1DCn = 预定MPWM信号应转变为有效与PWM信号实际转为有效之间的T2CK周期数
MSCON = 0B00110000; //Bit0: 0:T2睡眠时停止工作
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 0:睡眠时停止工作:1: 睡眠时保持工作。当T2时钟不是选择指令时钟的时候
TMR2IF = 0; //清TMER2中断标志
TMR2IE = 1; //使能TMER2的中断(配置成timer定时器时不注释)
TMR2ON = 1; //使能TMER2启动
PEIE = 1; //使能外设中断
GIE = 1; //使能全局中断
}
/*-------------------------------------------------
* 函数名:SendCtrl
* 功能: 发送数据函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void SendCtrl(void)
{
if (IRSendStatus == Status_NOSend) // 不发送的状态
{
IRSend_PIN_0;
SendBit = 0;
TxTime = 0;
}
else if (IRSendStatus == Status_Head) // 发送引导码
{
TxTime++;
if (TxTime < 17) // 发送9mS信号
{
IRSend_PIN_1;
}
else if (TxTime < 24) // 4.5mS不发送
{
IRSend_PIN_0;
}
else
{
TxTime = 0;
IRSendStatus = Status_Data;
}
IRSendData = IRData[0];
TxBit = 0x01;
}
else if(IRSendStatus == Status_Data) // 发送数据
{
if (IRSendData & TxBit) // 1,是1:3的时间
{
level1 = IRSend_HIGH_1;
level0 = IRSend_LOW_1;
}
else // 0,是1:1的时间
{
level1 = IRSend_HIGH_0;
level0 = IRSend_LOW_0;
}
TxTime++;
if (TxTime <= level1) // 发送信号
{
IRSend_PIN_1;
}
else if (TxTime <= (level0+level1)) // 不发送信号
{
IRSend_PIN_0;
}
else if (SendBit < 4) // 发送4位数据未完成
{
TxTime = 1;
IRSend_PIN_1;
SaveLastBit = IRSendData & TxBit;
TxBit <<= 1;
if (TxBit == 0x00) // 发送完一个字节
{
TxBit = 0x01;
SendBit++;
IRSendData = IRData[SendBit];
if (SendBit > 3) // 最后一位要注意,因为发送完了还要有一个脉冲
{
SendLastBit = 1;
}
}
}
else // 数据完成了,要补脉冲
{
if(SendLastBit)
{
TxTime++;
if(SaveLastBit)
{
if(TxTime < 3)
{
IRSend_PIN_0;
}
else if(TxTime < 4)
{
IRSend_PIN_1;
}
else
{
IRSend_PIN_0;
IRSendStatus = Status_NOSend;
IRSend_PIN_0;
SendLastBit = 0;
TxBit = 0;
TxTime = 0;
}
}
else
{
if(TxTime < 5)
{
IRSend_PIN_0;
}
else if(TxTime < 6)
{
IRSend_PIN_1;
}
else
{
IRSend_PIN_0;
IRSendStatus = Status_NOSend;
IRSend_PIN_0;
SendLastBit = 0;
TxBit = 0;
TxTime = 0;
}
}
}
}
}
}
/*-------------------------------------------------
* 函数名:interrupt ISR
* 功能: 中断处理,包括定时器0中断和外部中断
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void interrupt ISR(void)
{
//定时器0的中断处理
if(T0IE && T0IF) //13us
{
TMR0 = 239; //注意:对TMR0重新赋值TMR0在两个周期内不变化
T0IF = 0;
IRSendIO = ~IRSendIO; //翻转电平 产生38KHz信号
}
//定时器2的中断处理
if(TMR2IE && TMR2IF) //560us中断一次 红外每一位都是560uS的倍数
{
TMR2IF = 0;
SendCtrl();
SYSTime5S++;
//IRSendIO = ~IRSendIO;
}
}
/*-------------------------------------------------
* 函数名:main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main(void)
{
POWER_INITIAL();
TIMER0_INITIAL();
Timer2Inital();
GIE = 1; //开中断
while(1)
{
if(SYSTime5S >10000) //每隔5S发射一次
{
SYSTime5S = 0;
IRSendStatus = Status_Head;
}
}
}
INT
// Project: FT60E12x_INT.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 程序中DemoPortOut(PA4)输出100帧50Hz的占空比为50%的方波后, MCU进入睡眠, 等待外部中断的发生;当外部中断触发后,重复以上流程;
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*********************************************************
#include "SYSCFG.h"
//***********************宏定义*****************************
#define unchar unsigned char
#define DemoPortOut PA4
unchar FCount;
/*-------------------------------------------------
* 函数名:interrupt ISR
* 功能: 中断处理函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void interrupt ISR(void)
{
//PA2外部中断处理
if(INTE && INTF)
{
INTF = 0; //清PA2 INT 标志位
INTE = 0; //暂先禁止PA2中断
}
}
/*----------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
----------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000100;
TRISA = 0B00000100; //PA输入输出 0-输出 1-输入
//PA4->输出
PORTC = 0B00000000;
TRISC = 0B00000100; //PC输入输出 0-输出 1-输入
WPUA = 0B00000100; //PA端口上拉控制 1-开上拉 0-关上拉
//开PA2上拉
WPUC = 0B00000000; //PC端口上拉控制 1-开上拉 0-关上拉
//60系列PC口无上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//BIT5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//BIT4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//BIT3: UCFG1<1:0>为01时此位有意义。0:禁止LVR; 1:打开LVR
//BIT2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//BIT1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//BIT0: 当T2时钟不是选择指令时钟的时候
// 0: 睡眠时停止工作; 1: 睡眠时保持工作。
}
/*----------------------------------------------------
* 函数名称:DelayUs
* 功能: 短延时函数 --16M-2T--大概快1%左右.
* 输入参数:Time 延时时间长度 延时时长Time Us
* 返回参数:无
----------------------------------------------------*/
void DelayUs(unsigned char Time)
{
unsigned char a;
for(a=0;a<Time;a++)
{
NOP();
}
}
/*----------------------------------------------------
* 函数名称:DelayMs
* 功能: 短延时函数
* 输入参数:Time 延时时间长度 延时时长Time ms
* 返回参数:无
----------------------------------------------------*/
void DelayMs(unsigned char Time)
{
unsigned char a,b;
for(a=0;a<Time;a++)
{
for(b=0;b<5;b++)
{
DelayUs(197); //快1%
}
}
}
/*-------------------------------------------------
* 函数名: INT_INITIAL
* 功能: 中断初始化函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void INT_INITIAL(void)
{
TRISA2 =1; //SET PA2 INPUT
IOCA2 =0; //禁止PA2电平变化中断
INTEDG =1; //OPTION,INTEDG=1;PA2 INT 为上升沿触发
INTF =0; //清PA2 INT中断标志位
INTE =1; //使能PA2 INT中断
}
/*-------------------------------------------------
* 函数名:main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main()
{
POWER_INITIAL(); //系统初始化
while(1)
{
for(FCount=0;FCount<100;FCount++) //输出100次波形
{
DemoPortOut = 1;
DelayMs(10); //10ms
DemoPortOut = 0;
DelayMs(10);
}
INT_INITIAL(); //初始化外部中断
GIE = 1; //开总中断
SLEEP(); //睡眠
}
}
IIC
// Project: FT60E12x_IIC.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 此演示程序位60E12x_IIC的演示程序.该程序把0x55写入(24C02)0x12地址,后读0x12地址的值,判断是否写入成功
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
#include "SYSCFG.h"
//***********************宏定义*****************************
#define unchar unsigned char
#define IIC_SCL PA4
#define IIC_SDA PA2
#define SDA_OUT TRISA2 =0
#define SDA_IN TRISA2 =1
volatile unchar IICReadData;
/*-------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000000; //PA输入输出 0-输出 1-输入
//PA4->输出
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
WPUC = 0B00000000; //PC端口上拉控制 1-开上拉 0-关上拉
//60系列PC口无上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5:PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4:PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3:UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2:快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1:0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0:0:睡眠时停止工作:1: 睡眠时保持工作。当T2时钟不是选择指令时钟的时候
}
/*-------------------------------------------------
* 函数名称:DelayUs
* 功能: 短延时函数 --16M-4T--大概快1%左右.
* 输入参数:Time 延时时间长度 延时时长Time*2Us
* 返回参数:无
-------------------------------------------------*/
void DelayUs(unsigned char Time)
{
unsigned char a;
for(a=0;a<Time;a++)
{
NOP();
}
}
/*-------------------------------------------------
* 函数名:IIC_Start
* 功能: 产生IIC起始信号
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void IIC_Start(void)
{
SDA_OUT; //SDA线输出
IIC_SDA=1;
IIC_SCL=1;
DelayUs(2);
IIC_SDA=0; //开始:当SCL为高时,SDA由高变低
DelayUs(2);
IIC_SCL=0; //钳住I2C总线,准备发送或接收数据
DelayUs(2);
}
/*-------------------------------------------------
* 函数名:IIC_Stop
* 功能: 产生IIC停止信号
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void IIC_Stop(void)
{
SDA_OUT; //SDA线输出
IIC_SCL=0;
IIC_SDA=0; //停止:当SCL为高时,SDA由低变高
DelayUs(2);
IIC_SCL=1;
DelayUs(2);
IIC_SDA=1; //发送I2C总线结束信号
DelayUs(2);
}
/*-------------------------------------------------
* 函数名:IIC_Wait_Ack
* 功能: 等待应答信号到来
* 输入: 无
* 输出: 返回值:1,接收应答失败
* 0,接收应答成功
--------------------------------------------------*/
unsigned char IIC_Wait_Ack(void)
{
unsigned char ucErrTime=0;
SDA_IN; //SDA设置为输入
IIC_SDA=1;
DelayUs(1);
IIC_SCL=1;
DelayUs(1);
while(IIC_SDA)
{
ucErrTime++;
if(ucErrTime>250) //等待超时
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0; //时钟输出0
return 0;
}
/*-------------------------------------------------
* 函数名:IIC_Ack
* 功能: 产生ACK应答
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT; //SDA线输出
IIC_SDA=0;
DelayUs(1);
IIC_SCL=1;
DelayUs(1);
IIC_SCL=0;
}
/*-------------------------------------------------
* 函数名:IIC_NAck
* 功能: 不产生ACK应答
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT; //SDA线输出
IIC_SDA=1;
DelayUs(1);
IIC_SCL=1;
DelayUs(1);
IIC_SCL=0;
}
/*-------------------------------------------------
* 函数名:IIC_Send_Byte
* 功能: IIC发送一个字节
* 输入: 写入要发送的一个人字节数据txd
* 输出: 无
--------------------------------------------------*/
void IIC_Send_Byte(unsigned char txd)
{
unsigned char t;
SDA_OUT; //SDA线输出
IIC_SCL=0; //拉低时钟开始数据传输
for(t=0;t<8;t++)
{
if(txd&0x80)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
DelayUs(1);
IIC_SCL=1;
DelayUs(1);
IIC_SCL=0;
DelayUs(1);
}
}
/*-------------------------------------------------
* 函数名:IIC_Read_Byte
* 功能: IIC读一个字节
* 输入: 无
* 输出: 读出存储器里面的数据并返回receive
--------------------------------------------------*/
unsigned char IIC_Read_Byte(void)
{
unsigned char i,receive=0;
SDA_IN; //SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
DelayUs(1);
IIC_SCL=1;
receive<<=1;
if(IIC_SDA)receive++;
DelayUs(1);
}
IIC_NAck(); //发送nACK
return receive;
}
/*-------------------------------------------------
* 函数名:IIC_READ
* 功能: IIC读出制定位置的数据
* 输入: address
* 输出: 读出address存储器里面的数据iicdata
--------------------------------------------------*/
unsigned char IIC_READ(unsigned char address)
{
unsigned char iicdata = 0;
IIC_READ_Begin:
IIC_Start();
IIC_Send_Byte(0xa0);
if(IIC_Wait_Ack())goto IIC_READ_Begin;
IIC_Send_Byte(address); //填要读的数据地址
if(IIC_Wait_Ack())goto IIC_READ_Begin;
IIC_Start();
IIC_Send_Byte(0xa1);
if(IIC_Wait_Ack())goto IIC_READ_Begin;
iicdata=IIC_Read_Byte();
IIC_Stop();
return iicdata;
}
/*-------------------------------------------------
* 函数名:IIC_WRITE
* 功能: IIC把数据data写入制定的位置address
* 输入: address,data
* 输出: 无
--------------------------------------------------*/
void IIC_WRITE(unsigned char address,unsigned char data)
{
IIC_WRITE_Begin:
IIC_Start();
IIC_Send_Byte(0xa0);
if(IIC_Wait_Ack())goto IIC_WRITE_Begin;
IIC_Send_Byte(address);
if(IIC_Wait_Ack())goto IIC_WRITE_Begin;
IIC_Send_Byte(data);
if(IIC_Wait_Ack())goto IIC_WRITE_Begin;
IIC_Stop();
}
/*-------------------------------------------------
* 函数名: main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main(void)
{
POWER_INITIAL(); //系统初始化
IIC_WRITE(0x12,0x55); //0x55写入地址0x12
IICReadData = IIC_READ(0x12); //读取0x12地址EEPROM值
while(1)
{
NOP();
}
}
EEPROM
// Project: FT60E12x_EEPROM.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 此演示程序为60E12x EEPROM的演示程序.把0x55写入地址0x13,再读出该值
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*********************************************************
#include "SYSCFG.h"
//*********************宏定义******************************
#define unchar unsigned char
volatile unchar EEReadData;
/*-------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000000; //PA输入输出 0-输出 1-输入
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
OPTION = 0B00001000; //Bit3=1,WDT MODE,PS=000=WDT RATE 1:1
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5:PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4:PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3:UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2:快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1:0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0:0:睡眠时停止工作:1: 睡眠时保持工作。当T2时钟不是选择指令时钟的时候
}
/*----------------------------------------------------
* 函数名称:EEPROMread
* 功能: 读EEPROM数据
* 输入参数:EEAddr 需读取数据的地址
* 返回参数;ReEEPROMread 对应地址读出的数据
----------------------------------------------------*/
unchar EEPROMread(unchar EEAddr)
{
unchar ReEEPROMread;
EEADR = EEAddr;
RD = 1;
ReEEPROMread = EEDAT; //EEPROM的读数据 ReEEPROMread = EEDATA;
return ReEEPROMread;
}
/*----------------------------------------------------
* 函数名称:EEPROMwrite
* 功能: 写数据到EEPROM
* 输入参数:EEAddr 需要写入数据的地址
* Data 需要写入的数据
* 返回参数:无
----------------------------------------------------*/
void EEPROMwrite(unchar EEAddr,unchar Data)
{
GIE = 0; //写数据必须关闭中断
while(GIE); //等待GIE为0
EEADR = EEAddr; //EEPROM的地址
EEDAT = Data; //EEPROM的写数据 EEDATA = Data;
EEIF = 0;
EECON1 |= 0x34; //置位WREN1,WREN2,WREN3三个变量.
WR = 1; //置位WR启动编程
while(WR); //等待EE写入完成
GIE = 1;
}
/*-------------------------------------------------
* 函数名: main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main()
{
POWER_INITIAL(); //系统初始化
EEPROMwrite(0x13,0x55); //0x55写入地址0x13
EEReadData = EEPROMread(0x13); //读取0x13地址EEPROM值
while(1)
{
NOP();
}
}
LVD
// Project: FT60E12x_LVD.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 设置PA5为LVD检测脚,当PA5为高时,VDD正常,DemoPortOut输出LOW,当PA5为低时,VDD掉到了所设置的低电压以下,DemoPortOut输出HIGH.
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*********************************************************
#include "SYSCFG.h"
//***********************宏定义****************************
#define DemoPortOut PA4
/*-------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000000; //PA输入输出 0-输出 1-输入
//PA4-OUT
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 0:睡眠时停止工作:1: 睡眠时保持工作。
// 当T2时钟不是选择指令时钟的时候比较器,CxIN为数字IO口
PCON = 0B11010011;
//Bit7 LVD模块检测电压源选择 1:检测外部管脚PA5,0:检测内部电压
//Bit[6:4] 低电压侦测选择位。 101 3.0V
//Bit3 低电压侦测使能。 1:开启LVD侦测功能,0:关闭
//Bit2 低电压标志位,只读。 1:VDD掉了设置电压以下,0:VDD正常
//Bit1 上电复位标志,低有效。0:发生了上电复位,1:没有发生
//Bit0 低电压复位标志,低有效。0:发生了低电压复位,1:没有发生
}
/*-------------------------------------------------
* 函数名: main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main(void)
{
POWER_INITIAL(); //系统初始化
PCON |= 0B00001000; //开启LVD侦测功能
while(1)
{
if(PCON&0x04) //判断低电压标志位
{
DemoPortOut = 1; //侦测到低电压标志为1
}
else
{
DemoPortOut = 0; //VDD正常
}
}
}
LVD_PWM
// Project: FT60E12x_LVD_PWM.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 低电压检测与PWM联动,检测输出可作为PWM的刹车源。当检测到LVD事件时,PWM刹车,当LVD事件消除时,PWM1~PWM6继续输出10kHz占空比50%的波形。
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*************************************************
#include "SYSCFG.h"
/*-------------------------------------------------
* 函数名:interrupt ISR
* 功能: 中断处理
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void interrupt ISR(void)
{
//定时器2的中断处
if(TMR2IE && TMR2IF) //100us中断一次
{
TMR2IF = 0;
}
}
/*-------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000000; //PA输入输出 0-输出 1-输入
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000; //Bit0: 0:T2睡眠时停止工作
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 0:睡眠时停止工作:1:睡眠时保持工作。
// 当T2时钟不是选择指令时钟的时候
}
/*-------------------------------------------------
* 函数名: TIMER2_INITIAL
* 功能: 初始化设置定时器2
* 设置: 周期=(PR+1)*Tt2ck*TMR2预分频(蜂鸣器模式周期*2)
* =(199+1)*1/8000000*4=100us
* 脉宽=P1xDT*Tt2ck*TMR2预分频
* =100*1/8000000*4=50us
-------------------------------------------------*/
void PWM1_INITIAL (void)
{
T2CON0 = 0B00000001; //T2预分频1:4,后分频1:1
//Bit7: 0:无意义; 1:把PR2/P1xDTy缓冲值分别更新到PR2寄存器和P1xDTy_ACT
//Bit[6:3]: 定时器2输出后分频比选择 0000:1:1;0001:1:2;……1:16
//Bit2: 0:关闭定时器2;1:打开定时器2
//Bit[1:0]: 定时器2预分频选择 00:1;01:4;1x:16
T2CON1 = 0B00000000; //T2时钟来自系统时钟,PWM1连续模式
//Bit4: PWM模式选择 0:连续模式;1:单脉冲模式
//Bit3: 0:PWM模式;1:蜂鸣器模式
//Timer2时钟源选择:000:指令时钟;001:系统时钟;010:HIRC的2倍频;100:HIRC;101:LIRC
TMR2H = 0; //定时器2计数寄存器
TMR2L = 0;
PR2H = 0; //周期=(PR+1)*Tt2ck*TMR2预分频(蜂鸣器模式周期*2)
PR2L = 199;
P1ADTH = 0; //脉宽=P1xDT*Tt2ck*TMR2预分频(蜂鸣器模式没用到)
P1ADTL = 100;
P1OE = 0B00111111; //允许P1A0输出PWM(配置成timer定时器时这位清零)
//Bit7: 0:禁止P1C输出到管脚;1:充许P1C输出到管脚
//Bit6: 0:禁止P1B输出到管脚;1:充许P1B输出到管脚
//Bit[5:0]: 0:禁止P1Ax输出到管脚;1:充许P1Ax输出到管脚
P1POL = 0B00000000; //高电平有效
//Bit7: 0:P1C高电平有效 1:P1C低电平有效
//Bit6: 0:P1B高电平有效 1:P1B低电平有效
//Bit[5:0]: 0:P1Ax高电平有效 1:P1Ax低电平有效
P1CON = 0B10000000;
//Bit7: PWM 重启使能位
// 1 = 故障刹车时,P1BEVT位在退出关闭事件时自动清零,PWM自动重启
// 0 = 故障刹车时,必须用软件将P1BEVT清零以重启PWM
//Bit[6:0]:PWM死区时间设置
// P1DCn = 预定MPWM信号应转变为有效与PWM信号实际转为有效之间的T2CK周期数
PCON = 0B11010011;
//Bit7 LVD模块检测电压源选择 1:检测外部管脚PA5,0:检测内部电压
//Bit[6:4] 低电压侦测选择位。 101 3.0V
//Bit3 低电压侦测使能。 1:开启LVD侦测功能,0:关闭
//Bit2 低电压标志位,只读。 1:VDD掉了设置电压以下,0:VDD正常
//Bit1 上电复位标志,低有效。0:发生了上电复位,1:没有发生
//Bit0 低电压复位标志,低有效。0:发生了低电压复位,1:没有发生
P1BR0 = 0B00110000;
//Bit7 PWM故障事件状态位 1:发生了故障事件 0:未发生故障事件,PWM输出正常工作
//Bit[6:4] PWM故障源选择位 000=禁止故障刹车功能 001=BK0为低电平 010=BK0为高电平
// 011=LVDW=1 100=BK0为低电平或LVDW=1 101=BK0位高电平或LVDW=1
//Bit[3:2]: 故障下,P1B管脚的状态 00=高阻 01=无效电平 1X=有效电平
//Bit[1:0]: 故障下,P1A管脚的状态 00=高阻 01=无效电平 1X=有效电平
P1BR1 = 0B00000000;
//Bit[7:6] 故障下,P1C管脚的状态,只有当P1CALT为1时才有效 00=高阻 01输出0 1X=输出1
//Bit[5:4] 故障下,P1C管脚的状态,只有当P1CALT为1时才有效 00=高阻 01输出0 1X=输出1
//Bit3 P1C功能映射选择
//Bit2 P1B功能映射选择
//Bit[1:0] 故障下,P1C管脚的状态 00=高阻 01=无效电平 1X=有效电平
TMR2IF = 0; //清TMER2中断标志
TMR2ON = 1; //使能TMER2启动
PEIE = 1; //使能外设中断
GIE = 1; //使能全局中断
}
/*-------------------------------------------------
* 函数名: main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main(void)
{
POWER_INITIAL(); //系统初始化
PWM1_INITIAL(); //LVD,PWM1,TM2的初始化
PCON |= 0B00001000; //开启LVD侦测功能
while(1)
{
if(PCON&0x04) //判断低电压标志位
{
NOP(); //侦测到低电压标志为1
}
else
{
NOP();
}
}
}
MSCK
// Project: FT60E12x_MSCK.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 程序中读取快时钟测量慢时钟数据
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*******************************************************
#include "SYSCFG.h"
//***********************宏定义**************************
#define unint unsigned int
volatile unint TestBuff;
/*-------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000000; //PA输入输出 0-输出 1-输入
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//BIT5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//BIT4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//BIT3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//BIT2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//BIT1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//BIT0: 0:睡眠时停止工作:1: 睡眠时保持工作。当T2时钟不是选择指令时钟的时候
}
/*----------------------------------------------------
* 函数名称: DelayUs
* 功能: 短延时函数 --16M-2T--大概快1%左右.
* 输入参数: Time 延时时间长度 延时时长Time Us
* 返回参数: 无
----------------------------------------------------*/
void DelayUs(unsigned char Time)
{
unsigned char a;
for(a=0;a<Time;a++)
{
NOP();
}
}
/*----------------------------------------------------
* 函数名称:DelayMs
* 功能: 短延时函数
* 输入参数:Time 延时时间长度 延时时长Time ms
* 返回参数:无
----------------------------------------------------*/
void DelayMs(unsigned char Time)
{
unsigned char a,b;
for(a=0;a<Time;a++)
{
for(b=0;b<5;b++)
{
DelayUs(197); //快1%
}
}
}
/*-------------------------------------------------
* 函数名: SlowTimeTest
* 功能: 快时钟测量慢时钟
* 输入: 无
* 输出: 慢时钟时钟测量值TestTime
* 不开平均模式慢时钟频率=16M/TestTime(2T)
* 开平均模式慢时钟频率 = 16M/TestTime/4(2T)
--------------------------------------------------*/
unint SlowTimeTest()
{
unint TestTime;
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
//IRCF = 111,SCS = 1.
TMR2ON = 1; //开定时器2
CKMIF = 0; //清标志位
CKMAVG = 0; //关闭平均模式
//注:打开平均模式输出数据为四个周期的时钟数(单周期*4)
CKCNTI = 1; //使能快时钟测量位,开始测量
while(!CKMIF);
CKMIF = 0;
TestTime = SOSCPRH << 8;
TestTime = TestTime + SOSCPRL;
return TestTime;
}
/*-------------------------------------------------
* 函数名: main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main(void)
{
POWER_INITIAL(); //系统初始化
while(1)
{
TestBuff = SlowTimeTest(); //时钟测量值
//32768该数值≈488(不开平均模式-单周期)
//慢时钟= TestBuff/16(kHz)
NOP();
NOP();
NOP();
DelayMs(200); //延时200ms
}
}
PA_INT
// Project: FT60E12x_PA_INT.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 程序中DemoPortOut(PA4)输出100帧50Hz的占空比为50%的方波后,MCU进入睡眠,等待中断的发生;当每次PA2电平变化中断触发后,重复以上流程;
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*********************************************************
#include "SYSCFG.h"
//***********************宏定义****************************
#define unchar unsigned char
#define DemoPortOut PA4
unchar FCount;
unchar ReadAPin;
/*-------------------------------------------------
* 函数名:interrupt ISR
* 功能: 中断处理函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void interrupt ISR(void)
{
//PA电平变化中断**********************
if(PAIE && PAIF)
{
ReadAPin = PORTA; //读取PORTA数据清PAIF标志
PAIF = 0; //清PAIF标志位
PAIE = 0; //暂先禁止PA0中断
IOCA2 =0; //禁止PA0电平变化中断
}
}
/*----------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
----------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000100; //PA输入输出 0-输出 1-输入
//PA4-OUT
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00000100; //PA端口上拉控制 1-开上拉 0-关上拉
//开PA2上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 当T2时钟不是选择指令时钟的时候
// 0:睡眠时停止工作:1: 睡眠时保持工作
}
/*----------------------------------------------------
* 函数名称:DelayUs
* 功能: 短延时函数 --16M-2T--大概快1%左右.
* 输入参数:Time 延时时间长度 延时时长Time Us
* 返回参数:无
----------------------------------------------------*/
void DelayUs(unsigned char Time)
{
unsigned char a;
for(a=0;a<Time;a++)
{
NOP();
}
}
/*----------------------------------------------------
* 函数名称:DelayMs
* 功能: 短延时函数
* 输入参数:Time 延时时间长度 延时时长Time ms
* 返回参数:无
----------------------------------------------------*/
void DelayMs(unsigned char Time)
{
unsigned char a,b;
for(a=0;a<Time;a++)
{
for(b=0;b<5;b++)
{
DelayUs(197); //快1%
}
}
}
/*----------------------------------------------------
* 函数名称:DelayS
* 功能: 短延时函数
* 输入参数:Time 延时时间长度 延时时长TimeS
* 返回参数:无
----------------------------------------------------*/
void DelayS(unsigned char Time)
{
unsigned char a,b;
for(a=0;a<Time;a++)
{
for(b=0;b<10;b++)
{
DelayMs(100);
}
}
}
/*-------------------------------------------------
* 函数名: PA2_Level_Change_INITIAL
* 功能: PA端口(PA2)电平变化中断初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void PA2_Level_Change_INITIAL(void)
{
TRISA2 = 1; //SET PA2 INPUT
ReadAPin = PORTA; //清PA电平变化中断
PAIF = 0; //清PA INT中断标志位
IOCA2 = 1; //使能PA2电平变化中断
PAIE = 1; //使能PA INT中断
//GIE = 1; //使能全局中断
}
/*-------------------------------------------------
* 函数名: main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main()
{
POWER_INITIAL(); //系统初始化
while(1)
{
for(FCount=0;FCount<100;FCount++) //输出100次波形
{
DemoPortOut = 1;
DelayMs(10); //10ms
DemoPortOut = 0;
DelayMs(10);
}
PA2_Level_Change_INITIAL(); //初始化外部中断
GIE = 1; //开总中断
SLEEP(); //睡眠
}
}
PWM
// Project: FT60E12x_PWM.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: PWM1~PWM6输出10KHz占空比50%的波形
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*********************************************************
#include "SYSCFG.h"
/*-------------------------------------------------
* 函数名:interrupt ISR
* 功能: 中断处理
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void interrupt ISR(void)
{
//定时器2的中断处理
if(TMR2IE && TMR2IF) //50us中断一次 = 10KHz
{
TMR2IF = 0;
}
}
/*-------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //WDT 32KHz IRCF=111=16MHz/2=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000000; //PA输入输出 0-输出 1-输入
PORTC = 0B00000000;
TRISC = 0B11000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
WPUC = 0B00000000; //PC端口上拉控制 1-开上拉 0-关上拉
//60系列PC口无上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
//Bit7(PAPU)=0 ENABLED PULL UP PA
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5:PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4:PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3:UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2:快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1:0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0:0:睡眠时停止工作:1: 睡眠时保持工作。当T2时钟不是选择指令时钟的时候
}
/*-------------------------------------------------
* 函数名称:TIMER2_INITIAL
* 功能: 初始化设置定时器2
* 设置: 周期=(PR+1)*Tt2ck*TMR2预分频(蜂鸣器模式周期*2)
* =(199+1)*1/8000000*4=100us
* 脉宽=P1xDT*Tt2ck*TMR2预分频
* =100*1/8000000*4=50us
-------------------------------------------------*/
void PWM1_INITIAL (void)
{
T2CON0 = 0B00000001; //T2预分频1:4,后分频1:1
//Bit7: 0:无意义; 1:把PR2/P1xDTy缓冲值分别更新到PR2寄存器和P1xDTy_ACT
//Bit[6:3]: 定时器2输出后分频比选择 0000: 1:1;0001: 1:2;……1:16
//Bit2:0: 关闭定时器2;1:打开定时器2
//Bit[1:0]: 定时器2预分频选择 00:1;01:4;1x:16
T2CON1 = 0B00000000; //T2时钟来自系统时钟,PWM连续模式
//Bit4: PWM模式选择 0:连续模式;1:单脉冲模式
//Bit3: 0:PWM模式;1:蜂鸣器模式
//Bit[2:0] Timer2时钟源选择:
// 000:指令时钟;
// 001:系统时钟;
// 010:HIRC的2倍频;
// 100:HIRC;
// 101:LIRC
TMR2H = 0; //定时器2计数寄存器
TMR2L = 0;
PR2H = 0; //周期
PR2L = 199;
P1ADTH = 0; //脉宽
P1ADTL = 100;
P1OE = 0B00111111; //允许P1A0-5输出PWM(配置成timer定时器时这位清零)
//Bit7: 0:禁止P1C输出到管脚;1:允许P1C输出到管脚
//Bit6: 0:禁止P1B输出到管脚;1:允许P1B输出到管脚
//Bit5~Bit0: 0:禁止P1Ax输出到管脚;1:允许P1Bx输出到管脚
P1POL = 0B00000000; //高电平有效
//Bit7: 0:P1C高电平有效;1:P1C低电平有效
//Bit6: 0:P1B高电平有效;1:P1B低电平有效
//Bit5~Bit0: 0:P1Ax高电平有效;1:P1Ax低电平有效
P1CON = 0B00000000;
//Bit7:PWM 重启使能位
//1 = 故障刹车时,P1BEVT位在退出关闭事件时自动清零,PWM自动重启
//0 = 故障刹车时,必须用软件将P1BEVT清零以重启PWM
//Bit6~0:PWM1死区时间设置
//P1DCn = 预定MPWM信号应转变为有效与PWM信号实际转为有效之间的T2CK周期数
TMR2IF = 0; //清TMER2中断标志
TMR2ON = 1; //使能TMER2启动
PEIE = 1; //使能外设中断
GIE = 1; //使能全局中断
}
/*-------------------------------------------------
* 函数名: main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main()
{
POWER_INITIAL(); //系统初始化
PWM1_INITIAL(); //初始化T2
while(1)
{
NOP();
}
}
SLEEP
// Project: FT60E12x_SLEEP.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 此程序为FT60E12x-SLEEP睡眠演示程序,上电之后LED1、LED2同时置高约4s,然后置低,进入睡眠。测试FT60F12x的睡眠功耗:
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*********************************************************
#include "SYSCFG.h"
//***********************宏定义*****************************
#define led1 PA4
#define led2 PA5
/*-------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/4T=4MHz,0.25us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000000; //PA输入输出 0-输出 1-输入
//PA4,PA5-OUT
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 当T2时钟不是选择指令时钟的时候
// 0:睡眠时停止工作:1: 睡眠时保持工作
}
/*-------------------------------------------------
* 函数名称:DelayUs
* 功能: 短延时函数 --16M-4T--大概快1%左右.
* 输入参数:Time 延时时间长度 延时时长Time*2 Us
* 返回参数:无
-------------------------------------------------*/
void DelayUs(unsigned char Time)
{
unsigned char a;
for(a=0;a<Time;a++)
{
NOP();
}
}
/*-------------------------------------------------
* 函数名称:DelayMs
* 功能: 短延时函数
* 输入参数:Time 延时时间长度 延时时长Time ms
* 返回参数:无
-------------------------------------------------*/
void DelayMs(unsigned char Time)
{
unsigned char a,b;
for(a=0;a<Time;a++)
{
for(b=0;b<5;b++)
{
DelayUs(98); //快1%
}
}
}
/*-------------------------------------------------
* 函数名称:DelayS
* 功能: 短延时函数
* 输入参数:Time 延时时间长度 延时时长Time S
* 返回参数:无
-------------------------------------------------*/
void DelayS(unsigned char Time)
{
unsigned char a,b;
for(a=0;a<Time;a++)
{
for(b=0;b<10;b++)
{
DelayMs(100);
}
}
}/*-------------------------------------------------
* 函数名:main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main(void)
{
POWER_INITIAL(); //系统初始化
led1 = 1;
led2 = 1;
DelayS(4);
led1 = 0;
led2 = 0;
while(1)
{
CLRWDT(); //清看门狗
NOP();
SLEEP();
NOP();
}
}
SPI
// Project: FT60E12x_SPI.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 此演示程序为60E12x_SPI的演示程序.该程序写入0x55到(25C64)0x13地址,然后读取0x13地址值
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*********************************************************
#include "SYSCFG.h"
//***********************宏定义*****************************
#define unchar unsigned char
#define unint unsigned int
#define MISO PA4
#define MOSI PA2
#define SCK PA6
#define CS PA7
volatile unchar SPIReadData;
/*-------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/4=4MHz,0.25us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00010000;
TRISA = 0B00010000; //PA输入输出 0-输出 1-输入
//PA4-IN PA2-OUT
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00010000; //PA端口上拉控制 1-开上拉 0-关上拉
//开PA4上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
//Bit7(PAPU)=0 ENABLED PULL UP PA
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 0:睡眠时停止工作:1: 睡眠时保持工作。当T2时钟不是选择指令时钟的时候
}
/*-------------------------------------------------
* 函数名:init_25c64_io
* 功能: 25C64初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void init_25c64_io(void)
{
CS = 1;
SCK = 0;
MOSI = 0;
}
/*-------------------------------------------------
* 函数名:SPI_RW
* 功能: 主机输出以及输入一个字节
* 输入: data
* 输出: 根据接收的data输出给从机一个字节
--------------------------------------------------*/
unchar SPI_RW(unchar data)
{
unchar i;
for(i=0;i<8;i++)
{
if(data&0x80)
MOSI = 1; //输出 'uchar',MSB to MOSI
else
MOSI = 0;
NOP();
data <<= 1; //切换下一位到 MSB
SCK = 1; //SCK置高...
NOP();
if(MISO)
data |= 0x01;
else
data &= 0xFE;
NOP();
SCK = 0;
}
return data;
}
/*-------------------------------------------------
* 函数名:WriteEnable
* 功能: 写允许(将WEN置位)
--------------------------------------------------*/
void WriteEnable(void)
{
CS=0;
SPI_RW(0x06);
CS=1;
}
/*-------------------------------------------------
* 函数名:WriteDisable
* 功能: 写禁止(将WEN复位)
--------------------------------------------------*/
void WriteDisable (void)
{
CS=0;
SPI_RW(0x04);
CS=1;
}
/*-------------------------------------------------
* 函数名: SPI_ReadStatus
* 功能: 读取25C64芯片的状态。
* 返回值:状态寄存器数据字节
* 注: 25C64内部状态寄存器第0位=0表示空闲,0位=1表示忙。
--------------------------------------------------*/
unchar SPI_ReadStatus(void)
{
unchar status=0;
CS=0;
SPI_RW(0x05); //0x05读取状态的命令字
status = SPI_RW(0x00);
CS=1; //关闭片选
return status;
}
/*-------------------------------------------------
* 程序名:SPI_WriteStatus
* 功能: 写25C64芯片的状态寄存器。
* 只有BP1、BP0 (bit7、3、2)可以写、
* 注: 25c64内部状态寄存器第0位=0表示空闲,0位=1表示忙。
--------------------------------------------------*/
void SPI_WriteStatus(unchar Status)
{
CS=0;
SPI_RW(0X01); //0x01读取状态的命令字
SPI_RW(Status); //写入一个字节
CS=1; //关闭片选
}
/*-------------------------------------------------
* 程序名:SPI_Read
* 输入: 16位的地址
* 返回: 读取的数据
* 说明: 从25c64指定的地址读取一个字节
--------------------------------------------------*/
unchar SPI_Read(unint addr)
{
unchar spidata;
while(SPI_ReadStatus()&0x01); //判断是否忙
CS=0; //使能器件
SPI_RW(0x03); //发送读取命令
SPI_RW((unsigned char)((addr)>>8));
SPI_RW((unsigned char)addr);
spidata = SPI_RW(0x00); //读出数据
CS=1;
return spidata;
}
/*-------------------------------------------------
* 程序名:SPI_Write
* 输入: 地址,字节数据
* 说明: 将一个字节写入指定的地址
--------------------------------------------------*/
void SPI_Write(unint addr,unchar dat)
{
while(SPI_ReadStatus()&0x01); //判断是否忙
WriteEnable(); //SET WEL
CS=0; //使能器件
SPI_RW(0x02); //发送写命令
SPI_RW((unchar)((addr)>>8));
SPI_RW((unchar)addr);
SPI_RW(dat);
CS=1; //关闭片选
WriteDisable();
while(SPI_ReadStatus()&0x01);
}
/*-------------------------------------------------
* 函数名: main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main()
{
POWER_INITIAL(); //系统初始化
init_25c64_io();
SPI_Write(0x0013,0x55);
SPIReadData = SPI_Read(0x0013); //读取0x13地址值
while(1)
{
NOP();
}
}
TIMER0
// Project: FT60E12x_TIMER0.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: DemoPortOut输出60Hz占空比50%的波形-Timer0实现
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*********************************************************
#include "SYSCFG.h"
//***********************宏定义****************************
#define DemoPortOut PA4
/*-------------------------------------------------
* 函数名:interrupt ISR
* 功能: 中断处理
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void interrupt ISR(void)
{
//定时器0的中断处理
if(T0IE && T0IF) //8.192ms翻转一次≈60Hz
{
T0IF = 0;
DemoPortOut = ~DemoPortOut; //翻转电平
}
}
/*-------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000000; //PA输入输出 0-输出 1-输入
//PA4-OUT
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B01000000; //PA端口上拉控制 1-开上拉 0-关上拉
//开PA6上拉
OPTION = 0B00000000; //Bit3=0 TMR0 MODE,PS=000=TMR0 Rate 1:2
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 当T2时钟不是选择指令时钟的时候
// 0:睡眠时停止工作:1: 睡眠时保持工作。
}
/*----------------------------------------------------
* 函数名称:TIMER0_INITIAL
* 功能:初始化设置定时器
* 相关寄存器:T0CS T0SE PSA
* 设置TMR0定时时长=(1/系统时钟频率)*指令周期*预分频值*255
* =(1/16000000)*2*256*255=8.192ms
----------------------------------------------------*/
void TIMER0_INITIAL (void)
{
OPTION = 0B00000111;
//Bit5 T0CS Timer0时钟源选择
// 1-外部引脚电平变化T0CKI 0-内部时钟(FOSC/2)
//Bit4 T0CKI引脚触发方式 1-下降沿 0-上升沿
//Bit3 PSA 预分频器分配位 0-Timer0 1-WDT
//Bit[2:0] PS 8个预分频比 111 - 1:256
T0IF = 0; //清空T0软件中断
}
/*-------------------------------------------------
* 函数名: main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main(void)
{
POWER_INITIAL(); //系统初始化
TIMER0_INITIAL();
GIE = 1; //开中断
T0IE = 1; //开定时器/计数器0中断
while(1)
{
NOP();
}
}
TIMER2
// Project: FT60E12x_TIMER2.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 当DemoPortIn悬空或者高电平时,DemoPortOut输出5KHz占空比50%的波形-Tm2实现当DemoPortIn接地时,DemoPortOut输出高电平.关定时器
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//**********************************************************
#include "SYSCFG.h"
//***********************宏定义*****************************
#define DemoPortOut PA4
#define DemoPortIn PA6
/*-------------------------------------------------
* 函数名:interrupt ISR
* 功能: 定时器2中断处理程序
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void interrupt ISR(void)
{
//定时器2的中断处理
if(TMR2IE && TMR2IF) //100us中断一次 = 5kHz
{
TMR2IF = 0;
DemoPortOut = ~DemoPortOut; //翻转电平
}
}
/*-------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B01000000; //PA输入输出 0-输出 1-输入
//PA4-OUT RA6-IN
PORTC = 0B00000000;
TRISC = 0B11111111; //PC输入输出 0-输出 1-输入
WPUA = 0B01000000; //PA端口上拉控制 1-开上拉 0-关上拉
//开PA6上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=WDT RATE 1:1
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 当T2时钟不是选择指令时钟的时候
// 0:睡眠时停止工作:1: 睡眠时保持工作。
}
/*-------------------------------------------------
* 函数名称: TIMER2_INITIAL
* 功能: 初始化设置定时器2
* 设置TMR2定时时长=1/系统时钟频率*2*预分频值*后分频值*PR2
* =(1/16000000)*2*4*1*200=100us
-------------------------------------------------*/
void TIMER2_INITIAL (void)
{
T2CON0 = 0B00000001; //T2预分频1:4,后分频1:1
//Bit[6:3]: 定时器2输出后分频比 0000-1:1
//Bit2: 定时器2输出是能位 0-关闭 1-使能
//Bit[1:0]: 定时器2预分频比 01-1:4
T2CON1 = 0B00000000; //T2时钟来自系统时钟,PWM1连续模式
//Bit4: PWM单脉冲模式选择 0-连续 1-单脉冲
//Bit3: PWM蜂鸣器模式选择 0-PWM模式 1:蜂鸣器模式
//Bit[2:0]:Timer2时钟源选择 000-指令时钟
TMR2H = 0; //TMR2赋值
TMR2L = 0;
PR2H = 0; //PR赋值
PR2L = 200;
TMR2IF = 0; //清TMER2中断标志
TMR2IE = 1; //使能TMER2的中断(配置成timer定时器时不注释)
TMR2ON = 1; //使能TMER2启动
PEIE = 1; //使能外设中断
GIE = 1; //使能全局中断
}
/*-------------------------------------------------
* 函数名: main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main()
{
POWER_INITIAL(); //系统初始化
TIMER2_INITIAL(); //初始化T2
while(1)
{
if(DemoPortIn) //判断输入是否为高电平
{
TMR2IE = 1; //开定时器2
}
else
{
TMR2IE = 0; //关定时器2
DemoPortOut = 1;
}
}
}
UART
// Project: FT60E12x_UART.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 演示程序中波特率为9600,RXIO(PA2)每次收到外部串口发过来的数据后,TXIO(PA4)把收到的数据再发送出去。收起始位时是用电平变化中断识别,后面就关闭电平变化中断了。
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*********************************************************
#include "SYSCFG.h"
//**********************宏定义*****************************
#define uchar unsigned char
#define TXIO PA4 //串口的发送脚
#define RXIO PA2 //串口的接收脚
#define Bord 49 //通过定时器提供波特率
uchar RXFLAG = 0;
uchar ReadAPin;
/*-------------------------------------------------
* 函数名: POWER_INITIAL
* 功能: MCU初始化函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL(void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/4=4MHz,0.25us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000100; //PA输入输出 0-输出 1-输入
//PA4-OUT PA2-IN
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
OPTION = 0B00001000; //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
//Bit7(PAPU)=0 ENABLED PULL UP PA
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//Bit5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//Bit3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//Bit2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//Bit1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//Bit0: 当T2时钟不是选择指令时钟的时候
// 0:睡眠时停止工作:1: 睡眠时保持工作。
}
/*----------------------------------------------------
* 函数名:TIMER0_INITIAL
* 功能: 初始化设置定时器
* 输入: 无
* 输出: 无
* 说明: 设置TMR0定时时长=(1/系统时钟频率)*指令周期*预分频值*208
* =(1/16000000)*4*2*208=104us
----------------------------------------------------*/
void TIMER0_INITIAL (void)
{
OPTION = 0B00000000;
//Bit5: T0CS Timer0时钟源选择
// 1-外部引脚电平变化T0CKI 0-内部时钟(FOSC/2)
//Bit4: T0CKI引脚触发方式 1-下降沿 0-上升沿
//Bit3: PSA 预分频器分配位 0-Timer0 1-WDT
//Bit[2:0]: PS2 8个预分频比 000 - 1:2
TMR0 = Bord;
T0IF = 0; //清空T0软件中断
}
/*-------------------------------------------------
* 函数名: PA2_Level_Change_INITIAL
* 功能: PA端口(PA2)电平变化中断初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void PA2_Level_Change_INITIAL(void)
{
TRISA2 =1; //SET PA2 INPUT
ReadAPin = PORTA; //清PA电平变化中断
PAIF =0; //清PA INT中断标志位
IOCA2 =1; //使能PA2电平变化中断
PAIE =1; //使能 PA INT中断
//GIE =1; //使能全局中断
}
/*-------------------------------------------------
* 函数名:interrupt ISR
* 功能: 中断处理,包括定时器0中断和外部中断
* 说明: 定时器产生104uS中断,对应9600的波特率 1000000÷9600=104
--------------------------------------------------*/
void interrupt ISR(void)
{
//定时器0的中断处
if(T0IE && T0IF) //104us
{
TMR0 = Bord; //注意:对TMR0重新赋值TMR0在两个周期内不变化
T0IF = 0;
T0IE = 0;
}
//PA电平变化中断
if(PAIE && PAIF)
{
ReadAPin = PORTA; //读取PORTA数据清PAIF标志
PAIF = 0; //清PAIF标志位
if(RXIO == 0)
{
PAIE = 0; //暂先禁止PA电平变化中断
IOCA2 =0; //禁止PA2电平变化中断
RXFLAG = 1;
}
}
}
/*-------------------------------------------------
* 函数名: WaitTF0
* 功能: 查询定时器溢出后,在中断里关闭定时器后,再次打开定时器
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void WaitTF0( void )
{
while(T0IE);
T0IE=1;
}
/*-------------------------------------------------
* 函数名: WByte
* 功能: UART发送一个字节
* 输入: input
* 输出: 无
--------------------------------------------------*/
void WByte(uchar input)
{
//发送起始位
uchar i=8;
TXIO = 1;
TMR0 = Bord;
T0IE = 1;
WaitTF0();
TXIO=0;
WaitTF0();
//发送8位数据位
while(i--)
{
if(input&0x01) //先传低位
{
TXIO=1;
}
else
{
TXIO = 0;
}
WaitTF0();
input=input>>1;
}
//发送结束位
TXIO=(bit)1;
T0IE=0;
}
/*-------------------------------------------------
* 函数名:RByte
* 功能: UART接收一个字节
* 输入: 无
* 输出: Output
--------------------------------------------------*/
uchar RByte()
{
uchar Output=0;
uchar i=8;
T0IE=1; //启动Timer0
TMR0 = Bord;
WaitTF0();
T0IE=1; //启动Timer0
TMR0 = Bord;
WaitTF0(); //等过起始位
//发送8位数据位
while(i--)
{
Output >>=1;
if(RXIO)
{
Output |=0x80; //先收低位
}
WaitTF0(); //位间延时
}
T0IE=0; //停止Timer0
return Output;
}
/*-------------------------------------------------
* 函数名:main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main(void)
{
uchar rdata = 0;
POWER_INITIAL();
TIMER0_INITIAL();
PA2_Level_Change_INITIAL();
GIE = 1; //开中断
T0IE = 1; //开定时器/计数器0中断
while(1)
{
if(RXFLAG) //外部中断下降沿触发了
{
rdata = RByte();
WByte(rdata);
IOCA2 =1; //使能PA2电平变化中断
PAIE =1; //使能PA INT中断
RXFLAG = 0;
}
}
}
WDT
// Project: FT60E12x_WDT.prj
// Device: FT60E12X
// Memory: PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte
// Description: 程序中开启看门狗并将看门狗时间设置为32ms
// a. 主函数先在DemoPortOut脚输出一个高3ms低3ms的信号,
// b. 然后循环输出高1ms低1ms,500HZ的信号。
// 如果不在主程序中清看门狗,则每隔32ms单片机复位后,会重复输出a+b信号;
// 如果在主函数中清看门狗,则一直输出b信号
// RELEASE HISTORY
// VERSION DATE DESCRIPTION
// 1.1 24-2-21 修改文件头
//*********************************************************
#include "SYSCFG.h"
//***********************宏定义****************************
#define DemoPortOut PA4
/*-------------------------------------------------
* 函数名:POWER_INITIAL
* 功能: 上电系统初始化
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000000; //PA输入输出 0-输出 1-输入
//PA4-OUT
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
OPTION = 0B00001000; //Bit3=1,WDT MODE,PS=000=WDT RATE 1:1
PSRCA = 0B11111111; //源电流设置最大
PSRCC = 0B11111111;
PSINKA = 0B11111111; //灌电流设置最大
PSINKC = 0B11111111;
MSCON = 0B00110000;
//BIT5: PSRCAH4和PSRCA[4]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//BIT4: PSRCAH3和PSRCA[3]共同决定源电流。00:4mA; 11: 33mA; 01、10:8mA
//BIT3: UCFG1<1:0>为01时此位有意义。0:禁止LVR;1:打开LVR
//BIT2: 快时钟测量慢周期的平均模式。0:关闭平均模式;1:打开平均模式
//BIT1: 0:关闭快时钟测量慢周期;1:打开快时钟测量慢周期
//BIT0: 当T2时钟不是选择指令时钟的时候
// 0:睡眠时停止工作:1: 睡眠时保持工作。
}
/*-------------------------------------------------
* 函数名称:DelayUs
* 功能: 短延时函数--16M-2T--大概快1%左右.
* 输入参数:Time 延时时间长度 延时时长Time Us
* 返回参数:无
--------------------------------------------------*/
void DelayUs(unsigned char Time)
{
unsigned char a;
for(a=0;a<Time;a++)
{
NOP();
}
}
/*-------------------------------------------------
* 函数名称:DelayMs
* 功能: 短延时函数
* 输入参数:Time 延时时间长度 延时时长Time ms
* 返回参数:无
--------------------------------------------------*/
void DelayMs(unsigned char Time)
{
unsigned char a,b;
for(a=0;a<Time;a++)
{
for(b=0;b<5;b++)
{
DelayUs(197); //快1%
}
}
}
/*-------------------------------------------------
* 函数名称:WDT_INITIAL
* 功能: 初始化设置看门狗1S时间复位
* 设置定时时长=(1/32000)*16位预分频值*8位预分频值
=(1/32000)*1024*1=32ms
-------------------------------------------------*/
void WDT_INITIAL (void)
{
CLRWDT(); //清看门狗
PSA=0; //时钟分频分给WDT
WDTCON = 0B00001011; //WDTPS:0101-1:1024,PS:000-1:1
}
/*-------------------------------------------------
* 函数名: main
* 功能: 主函数
* 输入: 无
* 输出: 无
--------------------------------------------------*/
void main(void)
{
POWER_INITIAL(); //系统初始化
WDT_INITIAL();
DemoPortOut = 1;
DelayMs(3); //3ms
DemoPortOut = 0;
DelayMs(3); //3ms
while(1)
{
//CLRWDT(); //清看门狗
DemoPortOut = 1;
DelayMs(1); //1ms
DemoPortOut = 0;
DelayMs(1); //1ms
}
}
参考
辉芒微电子
辉芒微(FMD)单片机开发环境搭建
立创商城
立创eda
立创eda快速入门
小辉_Super
有大量的嵌入式的优质文章