📄 aaa.c.bak
字号:
#include <upsd3300.h>
#include <intrins.h>
#include <string.h>
#include <absacc.h>
//#include "upsd33_adc.h"
//#include <Turbo_adc.h>
//#include <Turbo_timer.h>
//#include <Turbo_PCA-PWM.h>
//#include <test.h>
#define uchar unsigned char
#define uint unsigned int
//#define PSD_REG_ADDR 0x0800 //PSD寄存器IO基址
#define scan P3 //键扫
#define POWK P1_7 //交流接触器开关,0有效
#define POWZ P4_7 //电阻短接,0有效
#define ST P4_6 //脉冲使能
#define RS P1_6 //液晶命令口
#define RW P1_5
#define E P1_4
#define PSD_REG_ADDR 0x0200
/*********管脚定义****************/
//#define lcdport PSD33_reg.DATAOUT_A //P4 //P4液晶数据口,必须用双通道IO
xdata PSD_REGS PSD33_reg _at_ PSD_REG_ADDR ;
uchar bdata temp; //判忙用字节
sbit busy = temp^7;
uchar keyv ;
uchar pinlv[3] = {0,0,0}; //频率值
uchar dianya[2] = {0,0}; //电压值
//uchar mm[3] = {1,6,0}; //调制度,30-210
uchar code OK[]={"OK"};
uchar i;
/******************************************************************************
* PWM变量定义
******************************************************************************/
/*------------------------------------------------------------------------------
Local Variable Declarations
------------------------------------------------------------------------------*/
//时钟周期为30ns,(板上33.1776M晶振)
//固定频率采样,载波频率5K,周期200us,计数值=200us/(30ns*12)=556
//采样周期 = 1/2载波周期 = 278
//long Fc;
long idata F;
long idata F_min;
uint data N; //载波比
long data M; //调制系数
uint data Ts; //采样周期 = 1/2 载波周期
long data Half_Ts; //1/2采样周期
long idata K_M; //调制系数放大倍数
long idata K_F; //输入频率放大倍数
//uint idata K_sin; //sin表放大倍数
//uint idata K_coe; //总放大倍数,K_M * K_sin;
//int idata dead_time;
uint data U_angle;
uint data V_angle;
uint data W_angle;
uint data K; //采样个数,偶数为顶点采样,奇数为底点采样
uint data U_Toff; //顶点采样开通延时
uint data U_Ton; //底点采样关断延时
uint data V_Toff;
uint data V_Ton;
uint data W_Toff;
uint data W_Ton;
uint Tm;
code uint u36 = 0x125;
unsigned char data P_flag,aa; //奇偶采样点标志
static unsigned int idata timer0_tick;
static unsigned int idata timer0_value;
static unsigned int idata timer1_tick;
static unsigned int idata timer1_value;
int data M_angle;
unsigned long idata Fm;
unsigned int data PCA0;
//0--180度正弦表
unsigned char code sin_table[181] = { 0,4,9,13,18,22,27,31,35,40,
44,49,53,57,62,66,70,75,79,83,
87,91,96,100,104,108,112,116,120,124,
128,131,135,139,143,146,150,153,157,160,
164,167,171,174,177,180,183,186,190,192,
195,198,201,204,206,209,211,214,216,219,
221,223,225,227,229,231,233,235,236,238,
240,241,243,244,245,246,247,248,249,250,
251,252,253,253,254,254,254,255,255,255,
255,255,255,255,254,254,254,253,253,252,
251,250,249,248,247,246,245,244,243,241,
240,238,236,235,233,231,229,227,225,223,
221,219,216,214,211,209,206,204,201,198,
195,192,190,186,183,180,177,174,171,167,
164,160,157,153,150,146,143,139,135,131,
128,124,120,116,112,108,104,100,96,91,
87,83,79,75,70,66,62,57,53,48,
44,40,35,31,27,22,18,13,9,4,0 };
/********************************************************************
*键盘码
********************************************************************/
uchar code key_tab[] =
{
0x01,0x02,0x03,0x0a,
0x04,0x05,0x06,0x0b,
0x07,0x08,0x09,0x0c,
0x0f,0x00,0x0e,0x0d,
};
/********************************************************************/
/*******************************函数声明*****************************/
/********************************************************************/
/*---------------------------------------------------------------
* LCD函数声明
*---------------------------------------------------------------*/
void lcdbusytest();
void writelcdcom(uchar com);
void writelcddat(uchar dat);
void mdelay(uchar j); //upsd 40M延时
void initlcd(); //初始化
void clrlcd(); //清屏
void printchar(uchar xpos,uchar ypos,uchar str); //写一个字符
void printstr(uchar xpos,uchar ypos,uchar *str); //写字符串
/*-------------------------------------------------------------
* 键盘扫描
*-------------------------------------------------------------*/
uchar getkey (void);
/*-------------------------------------------------------------
* ADC 程序声明
-------------------------------------------------------------*/
void ADC_EnableAll(void) ;
void ADC_Init (unsigned char channel);
unsigned int ADC_Read( unsigned char channel );
/*-------------------------------------------------------------
* 得到电压电压值,并在液晶上显示
-------------------------------------------------------------*/
void getVA (uchar channel);
/*-------------------------------------------------------------
* 得到功率和频率
-------------------------------------------------------------*/
void getPf (void);
/*******************************************************************
************************PWM部分声明*********************************
*******************************************************************/
/*-------------------------------------------------------------
//定时器0中断服务程序,PWM
//定时器0用于产生采样周期的定时中断,采样周期Ts =1/2载波周期 = 278 时钟周期
-------------------------------------------------------------*/
static void timer0_isr (void); //interrupt TF0_VECTOR using 1
/*-------------------------------------------------------------
* int sin_angle(long angle )
*功能描述:角度换算函数,使角度值控制在180以内
*
-------------------------------------------------------------*/
int sin_angle(long angle );
/*-------------------------------------------------------------
* void first(void )
*第一个采样点计算函数,在K=0时计算
-------------------------------------------------------------*/
void first(void );
/*-------------------------------------------------------------
*定时器0初始化
-------------------------------------------------------------*/
void timer0_init (void);
/*--------------------------------------------------------------------
*PCA中断服务程序
---------------------------------------------------------------------*/
static void PCA_isr (void); //interrupt PCA_VECTOR using 1
/*-------------------------------------------------------------------
* PCA0初始化
--------------------------------------------------------------------*/
void PCA_init() ;
void pwmwork();
/***********************PWM声明结束***********************************/
/*********************************************************************
***************************函数声明结束*******************************
**********************************************************************/
/****************************************************************
*延时子程序,1ms
****************************************************************/
void delay1ms(uint x)
{
uint i;
while(x--) //((11+7*i)*x+5 )T
{ i= 450;
while((i--)>0); //i=141,x=1,t=1003T
}
}
/******************************************************************
* uchar keyscan()
*功能:键盘扫描程序
*说明: 4*4键盘,无上拉电阻。P0~P3为行输出,P4~P7为列输入
*返回值:0x(lie)(hang)
******************************************************************/
uchar getkey (void)
{
static uchar kn;
uchar lie=0,hang,x=0;
//E = 0;
//RS = 0;
scan = 0xf0;
if((scan & 0xf0) !=0xf0)
{ delay1ms(10);
if((scan & 0xf0) !=0xf0)
{ hang = 0xfe;
for(i=0;i<4;i++ )
{ scan = hang;
if((scan & 0xf0) != 0xf0)
{
lie = ~(scan | 0x0f );
switch (lie)
{ case 0x10:kn = *(key_tab + i);break;
case 0x20:kn = *(key_tab+i+4) ;break;
case 0x40:kn = *(key_tab+i+8) ;break;
case 0x80:kn = *(key_tab+i+12) ;break;
default:break;
}
return( kn);
}
else hang = (hang<<1)|0x01;
}
}
}
return(kn);
}
/**********延时子程序*************/
void mdelay(uchar j)
{uint i;
for(;j>0;j--)
{ for(i=0;i<200;i++)
{;}
}
}
/**********判忙子程序*************/
void lcdbusytest()
{
PSD33_reg.DATAOUT_A = 0xff;
// lcdport=0xff;
RS=0;
RW=1;
E=1;
PSD33_reg.DIRECTION_A =0; //PB为输入模式
do{temp=PSD33_reg.DATAIN_A;} while(busy);
//do{temp=lcdport;}while(busy);
E=0;
PSD33_reg.DIRECTION_A =0xff;
}
/*********写命令******************/
void writelcdcom(uchar com)
{
lcdbusytest();
RS=0;
RW=0;
E=1;
PSD33_reg.DATAOUT_A = com;
//lcdport=com;
E=0;
}
/**********写数据****************/
void writelcddat(uchar dat)
{
lcdbusytest();
RS=1;
RW=0;
E=1;
PSD33_reg.DATAOUT_A = dat;
//lcdport=dat;
E=0;
}
/***********LCD清屏****************/
void clrlcd()
{writelcdcom(0x01);}
/***********LCD初始化**************/
void init_lcd()
{ mdelay(15);
RS=0;
RW=0;
E=1;
PSD33_reg.DATAOUT_A = 0x38;
// lcdport=0x38;
E=0;
mdelay(5);
RS=0;
RW=0;
E=1;
PSD33_reg.DATAOUT_A = 0x38;
//lcdport=0x38;
E=0;
mdelay(5);
RS=0;
RW=0;
E=1;
PSD33_reg.DATAOUT_A = 0x38;
// lcdport=0x38;
E=0;
writelcdcom(0x38);
writelcdcom(0x08);
clrlcd();
writelcdcom(0x06);
writelcdcom(0x0c);
}
/*********写一个字符****************/
void printchar(uchar xpos,uchar ypos,uchar str)
{uchar m=0;
switch (ypos)
{ case 0: xpos|=0x80;break;
case 1: xpos|=0xc0;break;
default: break;
}
writelcdcom(xpos);
writelcddat(str);
}
/*********写字符串函数*************/
void printstr(uchar xpos,uchar ypos,uchar *str)
{
//uchar n;
uchar m=0;
switch (ypos)
{ case 0: xpos|=0x80;break; //写入显示地址要求D7恒为高电平
case 1: xpos|=0xc0;break;
default: break;
}
writelcdcom(xpos); //此处的Xpos已转换为LCM的显示寄存器实际地址
for(i=0;i<strlen(str);i++)
{
writelcddat(str[m++]);
}
}
/*****************************************************************************
* ADC_EnableAll()
*功能:ADC使能,设置P1口通道为ADC输入,选择ADC时钟频率
*参数:无
******************************************************************************/
void ADC_EnableAll(void)
{
ACON = 0; // 关闭ADC
ADCPS =(0x08 + 1); //使能ADC时钟,设置时钟频率
_nop_();
_nop_();
P1SFS0 |= 0x07;
P1SFS1 |= 0x07; // 选择P1口相应位为ADC输入
ACON = 0x20;
// 使能ADC;Enable ADC
// NOTE: USER CODE MUST WAIT AT LEAST 20 MS before calling ADC_Read (Using the ADC)
}
/******************************************************************************
* ADC_Init(channel)
*功能描述:ADC初始化,选择模拟通道输入,初始化时钟,关闭ADC中断
*参 数:channel - uchar 选择ADC通道
*注 意:当ADC通道改变得时候,此子程序一定要被调用
*****************************************************************************/
void ADC_Init (unsigned char channel)
{
unsigned char temp;
ACON = 0;
temp = (0x01) << channel; // 选择通道
P1SFS0 |= temp;
P1SFS1 |= temp; // 设置P1口相应位为ADC输入
ADCPS =(0x08 + 1); // 使能ADC时钟,设置时钟频率
_nop_();
ACON = 0x20; // 允许ADC转换
// NOTE: USER CODE MUST WAIT AT LEAST 20 MS before calling ADC_Read (Using the ADC)
}
/******************************************************************************
* uint ADC_Read(channel)
*功能描述:读A/D转换后的数据
*参 数:channel,初始化程序中选择的通道
*返 回 值:ADC转换结果,12位
*注 意:该子程序调用前,ADC_Init()必须先被调用
*******************************************************************************/
unsigned int ADC_Read( unsigned char channel )
{
unsigned int temp_ADC_result;
ACON &= 0xE0; //清除输入通路 ~(00101110B) = (11010001B)
ACON |= (channel<<2); //选择通路
_nop_ ();
_nop_ ();
ACON |= 0x02; //开始ADC转换
_nop_ (); //延时一个机器周期: ADST: 1->0
while( (ACON & 0x01) != 1 ); //等待转换结束
// Note: For increased ADC accuracy, the while loop above should be
// replaced with code that puts the MCU into Idle mode via PCON
// and makes use of the ADC interrupt to exit the Idle mode.
// The user would need to enable the ADC int and define the ADC ISR.
temp_ADC_result = (ADAT1<<8)+ADAT0; //Calculate ADC conversion result
return (temp_ADC_result);
}
/*******************************************************************************
* int sin_angle(long angle )
*功能描述:角度换算函数,使角度值控制在180以内
*
********************************************************************************/
int sin_angle(long angle )
{
int Mod_data;
Mod_data = (int)angle/180;
switch (Mod_data )
{
case 0:
M_angle = sin_table[angle];
break;
case 1:
M_angle = -sin_table[angle - 180];
break;
case 2:
M_angle = sin_table[angle - 360];
break;
case 3:
M_angle = -sin_table[angle - 540];
break;
}
return(M_angle);
}
/*******************************************************************************
* void first(void )
*第一个采样点计算函数,在K=0时计算
*******************************************************************************/
void first(void )
{
U_angle = K*180/N; //U相在K=0时计算
V_angle = U_angle + 120;
W_angle = U_angle + 240;
U_Toff = ((Half_Ts * (0xffff - M*(sin_angle(U_angle))))>>16);
V_Toff = ((Half_Ts * (0xffff - M*(sin_angle(V_angle))))>>16);
W_Toff = ((Half_Ts * (0xffff - M*(sin_angle(W_angle))))>>16);
P_flag = 0;
}
/*------------------------------------------------------------------------------
timer0_isr()
This function is an interrupt service routine for TIMER 0. It should never
be called by a C or assembly function. It will be executed automatically
when TIMER 0 overflows.
This ISR stops timer0, adjusts the counter so that another interrupt occurs in
10ms, and then restarts the timer.
------------------------------------------------------------------------------*/
//定时器0中断服务程序
//定时器0用于产生采样周期的定时中断,采样周期Ts =1/2载波周期 = 278 时钟周期
static void timer0_isr (void) interrupt TF0_VECTOR using 1
{
TR0 = 0; /* stop timer 0 */
TL0 = (timer0_value & 0x00FF);
TH0 = (timer0_value >> 8);
TR0 = 1; /* start timer 0 */
////////////////////////////////////////////
////将上一次定时器中断计算的延时值送入TCM0,TCM1,TCM2的比较寄存器
//
//
////取当前PCA0的计数值
PCA0 = PCACL0 + (PCACH0 << 8 );
//
////实际延时时间应加上PCA0的当前计数值
//
U_Toff += PCA0;
V_Toff += PCA0;
W_Toff += PCA0;
U_Ton += PCA0;
V_Ton += PCA0;
W_Ton += PCA0;
//
//
////偶数顶点采样使用Toff,奇数底点采样使用Ton
if ( P_flag==0)
{
CAPCOML0 = (U_Toff & 0x00FF);
CAPCOMH0 = (U_Toff >> 8);
CAPCOML1 = (V_Toff & 0x00FF);
CAPCOMH1 = (V_Toff >> 8);
CAPCOML2 = (W_Toff & 0x00FF);
CAPCOMH2 = (W_Toff >> 8);
}
else
{
CAPCOML0 = (U_Ton & 0x00FF);
CAPCOMH0 = (U_Ton >> 8);
CAPCOML1 = (V_Ton & 0x00FF);
CAPCOMH1 = (V_Ton >> 8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -