📄 main.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name: main.c
** Last modified Date: 2004-09-16
** Last Version: 1.0
** Descriptions: The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by: Chenmingji
** Created date: 2004-09-16
** Version: 1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by: Chenxibing
** Modified date: 2005-01-14
** Version:
** Descriptions: SPI实验,74HC595驱动7段数码管。
**
********************************************************************************************************/
//程序名:keyboard_display_I2C_PWM_4_AD_4_CAP_4
//----------------------程序头-----------------------------------
#include "config.h"
#define HC595_CS (1 << 29) // P0.29口为74HC595的片选
#define KEY (1 << 5) // P0.5口(MISO)为按键输入脚
#define Uo_def CS[0] //设定的电压 (第1级的)
#define Uo_test CS[1] //实测电压
#define Vref CS[2] //基准电压?????????????
#define Duty CS[3] //占空比的分子
//#define Uin CS[4]
#define Uo2_def CS[4] //设定的电压(第2级的)
#define Uo2_test CS[5] //实测电压
#define Duty2 CS[7] //占空比的分子
#define AD2SHOW CS[6] //AD2出的值
uint32 Uin=10000; //输入电压, mV
uint8 T0Flag = 0; //定时中断标志
uint16 CS[8]={0,0,0,0,0,0,0,0};
uint8 data_buf[12];
uint8 DATA0[8],DATA1[8];
uint8 digitable[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uint8 selectable[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uint8 x=0,y=0,k=0; //指针型变量,k对DATA0&DATA1&selectable;x&y对digitable;
uint8 w=0; //计数寄存器
uint8 SF=0; //闪烁标志位
uint8 TK=0x09; //按键按下位寄存器
uint8 M=0,R=0; //按键选项寄存器
uint8 Display=0; //显示内容积存器
uint32 CAP1_1=0,CAP1_2=0,CAP1_3=0,CAP1_4=0;
uint32 CAP2_1=0,CAP2_2=0,CAP2_3=0,CAP2_4=0; //定义捕获值寄存器组
uint32 PLS1=0,PLS2=0,PLS3=0,PLS4=0; //捕获脉冲总次数寄存器
uint8 H1=0,H2=0,H3=0,H4=0; //首次捕获标志位
uint16 N1=0,NP1=0,N2=0,NP2=0,N3=0,NP3=0,N4=0,NP4=0; //捕获次数寄存器及其暂存器
uint16 F1=0,F2=0,F3=0,F4=0; //未知信号频率寄存器
uint16 ADC_Data1[8]={0,0,0,0,0,0,0,0}; //AD转换结果暂存区
uint16 ADC_Data2[8]={0,0,0,0,0,0,0,0};
uint16 ADC_Data3[8]={0,0,0,0,0,0,0,0};
uint16 ADC_Data4[8]={0,0,0,0,0,0,0,0};
uint8 SENT_F; //送数显示执行标志位
uint16 ADC_Data; //第1级 AD值的寄存器
uint16 ADC2_Data; //第2级 AD值的寄存器
uint16 dDuty; //第1级 占空比增量
uint16 S_Flag; //????????
uint16 rcv_data; //????????
uint16 dUo; //第1级测量电压增量
uint16 Adj_Flag; //调整时间标志
uint32 sum_data; //AD 累加和
uint32 adc_count; //AD 次数
uint16 display = 2; //屏幕寄存器:1-为第1屏 2-为第2屏
uint16 dDuty2; //第2级 占空比增量
uint16 S_Flag2; //????????
uint16 dUo2; //第2级测量电压增量
uint32 sum2_data; //AD2 累加和
uint32 adc2_count; //AD2 次数
//………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………
/*********************************************************************************************************
** 函数名称 :delays()
** 函数功能 :长软件延时
** 入口参数 :dly 延时参数,值越大,延时越久
** 出口参数 :无
**********************************************************************************************************/
void delays(void)
{ uint8 i,j;
for(i=100;i>0;i--)
for(j=50;j>0;j--);
}//………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………
/***************TIMER0 初始化*************************************************************
** 函数名称:Timer0_InitExt()
** 功能描述:TIMER0 初始化
** 入口参数:无
** 出口参数:无
*******************************************************************************************/
void Timer0_InitExt(void)
{
T0TC = 0; /* 定时器设置为0 */
T0PR = 0; /* 时钟不分频 */
T0MCR = 0x03; /* 设置T0MR0匹配后复位T0TC,并产生中断标志 */
T0MR0 = Fpclk/400; /* 2.5毫秒定时 */
T0TCR = 0x01; // 启动定时器
}
/*************TIMER0 中断服务程序****************************************************************
** 函数名称:IRQ_Timer0()
** 功能描述:TIMER0 中断服务程序
** 入口参数:无
** 出口参数:无
*******************************************************************************************/
void __irq IRQ_Timer0(void)
{
Adj_Flag++; //A/D采样,调整时间到标志,2.5*8=20ms调整一次
T0Flag = 1; // T0中断标志置位
T0IR = 0x01; // 清除中断标志
VICVectAddr = 0; // 向量中断处理结束 清除中断标志
}
/************设置定时器0中断IRQ************************************************************
** 函数名称:IRQ_Init()
** 功能描述:设置定时器0&1及I2C中断IRQ
** 入口参数:无
** 出口参数:无
*******************************************************************************************/
void IRQ_Init(void)
{
VICIntSelect = 0x00000000; // 设置所有的通道为IRQ中断
VICVectCntl0 = 0x20 |0x04; // Timer0分配到IRQ slot0,即最高优先级
VICVectAddr0 = (uint32)IRQ_Timer0; // 设置中断服务程序地址
VICIntEnable = 1 << 0x04; // 使能定时器0中断
}
//…………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………
//二进制数转BCD码子程序0
void CONVBIT0(uint16 num,uint8 hor)
{
DATA0[hor] = num%10/1;
DATA0[hor+1] = num%100/10;
DATA0[hor+2] = num%1000/100;
DATA0[hor+3] = num/1000;
return;
}
//二进制数转BCD码子程序1
void CONVBIT1(uint16 num,uint8 hor)
{
DATA1[hor] = num%10/1;
DATA1[hor+1] = num%100/10;
DATA1[hor+2] = num%1000/100;
DATA1[hor+3] = num/1000;
return;
}
/********************************************************************************************************
** 函数名称:MSPI_Init()
** 函数功能:初始化SPI接口,设置为主机。
** 入口参数:无
** 出口参数:无
*********************************************************************************************************/
void MSPI_Init(void)
{
S0PCCR = 0x52; // 设置SPI时钟分频
S0PCR = (0 << 3) | // CPHA = 0, 数据在SCK 的第一个时钟沿采样
(1 << 4) | // CPOL = 1, SCK 为低有效
(1 << 5) | // MSTR = 1, SPI 处于主模式
(0 << 6) | // LSBF = 0, SPI 数据传输MSB (位7)在先
(0 << 7); // SPIE = 0, SPI 中断被禁止
}
/********************************************************************************************************
** 函数名称:MSPI_SendData()
** 函数功能:向SPI总线发送数据。
** 入口参数:data 待发送的数据
** 出口参数:返回值为读取的数据
********************************************************************************************************/
uint8 MSPI_SendData(uint8 data)
{
SPI_SPDR = data;
while( 0 == (SPI_SPSR & 0x80)); // 等待SPIF置位,即等待数据发送完毕
return(SPI_SPDR);
}
/********************************************************************************************************
** 函数名称:PWM_Init()
** 函数功能:PWM初始化
** 入口参数:无
** 出口参数:无
*********************************************************************************************************/
void PWM_Init(void)
{
PWMPR = 0x00; // 不分频,计数频率为Fpclk
PWMMCR = 0x02; // 设置PWMMR0匹配时复位PWMTC
PWMPCR = 0x0A00; // 允许PWM1.3输出,单边PWM
PWMMR0 = Fpclk/1000; // 设置PWM频率 10KHz
PWMMR1 = (Duty2 * PWMMR0) / 10000 ; // 占空比2
PWMMR3 = (Duty * PWMMR0) / 10000 ; // 占空比
PWMLER = 0x0B; // PWM0和PWM3, 1 匹配锁存
PWMTCR = 0X02; //复位
PWMTCR = 0X09; //启动PWM输出
}
/********************************************************************************************************/
/* 进行ADC模块设置 */
//AD初始化
//*******************************************************************************************************
void AD_Init(void)
{
AD0CR = (1 << 3) | // SEL=8,选择通道3
((Fpclk / 1000000 - 1) << 8) | // CLKDIV=Fpclk/1000000-1,转换时钟为1MHz
(0 << 16) | // BURST=0,软件控制转换操作
(0 << 17) | // CLKS=000, 使用11clock转换
(1 << 21) | // PDN=1,正常工作模式
(0 << 22) | // TEST1:0=00,正常工作模式
(1 << 24) | // START=1,直接启动ADC转换
(0 << 27); // 直接启动ADC转换时,此位无效
delays();
ADC_Data = AD0DR; // 读取ADC结果,并清除DONE标志位,为下次准备
}
/********************************************************************************************************
** 函数名称:ADC()
** 函数功能:AD转换程序
** 入口参数:无
** 出口参数:无
*********************************************************************************************************/
//启动 第1级 AD,并读取AD后的结果
//*********************************************************************
void StartADC(void)
{
AD0CR = (AD0CR & 0xffffff00) |
(1 << 3) | // 通道3 AD0.3
(1 << 24); // 进行第一次转换
while ((AD0DR & 0x80000000) == 0); // 等待转换结束
AD0CR = AD0CR | (1 << 24); // 再次启动转换
while ((AD0DR & 0x80000000) == 0); // 等待转换结束
ADC_Data = AD0DR; // 读取ADC结果
ADC_Data = (ADC_Data >> 6) & 0x3ff; //真正的结果
}
//*********************************************************************
//启动 第2级 AD2,并读取AD后的结果
//对第2级的输出进行采样
//*********************************************************************
void StartADC2(void)
{
AD0CR = (AD0CR & 0xffffff00) |
(1 << 5) | // 通道5 AD0.5
(1 << 24); // 进行第一次转换
while ((AD0DR & 0x80000000) == 0); // 等待转换结束
AD0CR = AD0CR | (1 << 24); // 再次启动转换
while ((AD0DR & 0x80000000) == 0); // 等待转换结束
ADC2_Data = AD0DR; // 读取ADC结果
ADC2_Data = (ADC2_Data >> 6) & 0x3ff; //真正的结果
}
/*================================================================
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
int main (void)
{// add user source code
//Uin = 10000; //mv
//CS[1] = 5000;
Uo_def = 8000; //第1级 的相关设定
Uo_test = 0;
Vref = 2440;
Duty = (Uo_def * 10000 )/ Uin ; //万份之几 的占空比( 扩大了10000倍的)
//Duty = (uo_def / uin) * 10000; //不能这样写,因为前面除了以后是小于1的,系统取整后为0,要先做乘法!
Uo2_def = 3000; //第2级 的相关设定
Uo2_test = 0;
Duty2 = (Uo2_def * 10000 * 10) / ((3300 * 10) * 2) ; //万份之几 的占空比( 扩大了10000倍的)
PINSEL0 = (PINSEL0 & (~0X03)) | (1 << 1) ; //PWM1输出 P0.0 --控制第2级的
PINSEL0 = (PINSEL0 & (~(0X03 << 2))) | (1 << 3); //PWM3输出 P0.1 --控制第1级的
PINSEL1 = (PINSEL1 & (~(0X03 << 20 ))) | (0X01 << 20) ; //AIN5 输入 P0.26 第2级
PINSEL1 = (PINSEL1 & (~(0X03 << 28 ))) | (0X01 << 28) ; //AIN3 输入 P0.30 第1级
IO0DIR = HC595_CS;
IRQEnable(); //IRQ中断使能
IRQ_Init();
Timer0_InitExt();
MSPI_Init();
PWM_Init();
AD_Init();
while (1)
{
if (T0Flag==1) //定时到 if1
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
if(T0Flag) //中断定时到2.5ms
{
while(w==80) //显示数据刷新时间到,执行数据变换. 2.5*80=200ms
{
if(M==0) //如果M=0表示运行态,显示运行参数。
{//
if (display == 2) //显示第2屏幕
{
CONVBIT0(CS[4],0); //第2级 设定电压 //第一行低4位数码
CONVBIT0(CS[5],4); //第2级 实测电压 //第一行高4位数码
CONVBIT1(CS[6],0); //第2级 占空比 //第二行低4位数码
CONVBIT1(CS[7],4); //第2级 A/D出来的10bit //第二行高4位数码
}
else //显示第1屏幕
{
CONVBIT0(CS[0],0); //第1级 设定电压 //第一行低4位数码
CONVBIT0(CS[1],4); //第1级 实测电压 //第一行高4位数码
CONVBIT1(CS[2],0); //第1级 基准电压 //第二行低4位数码
CONVBIT1(CS[3],4); //第1级 占空比 //第二行高4位数码
}
}//
w=0; //清除显示刷新计数器
if(SF) //闪烁标志取反
SF=0;
else
SF=1;
}
//--------------------------------------------------------------------------------------------------------
if(M==0) //显示扫描送运行参数
{
x=DATA0[k];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -