?? have_current_motor.c
字號:
#include"F240REGS.H"
//@@@@@@@@@@@@@液晶顯示程蠤@@@@@@@@@@@@@@@@@@@@@@
#define NOP() asm(" nop")
#define lcd_data_port PEDATDIR //八位數據
#define lcd_data_ddr PEDATDIR //引腳方向定義
#define lcd_busy_pin PEDATDIR
#define lcd_busy_ddr PEDATDIR
#define lcd_control_port PCDATDIR
#define lcd_control_ddr PCDATDIR
#define lcd_RS_DAT 0x0004 //PORTC^2
#define lcd_RW_DAT 0x0008 //PORTC^3
#define lcd_EN_DAT 0x0010 //PORTC^4
#define lcd_RS_DIR 0x0400 //PORTC^2
#define lcd_RW_DIR 0x0800 //PORTC^3
#define lcd_EN_DIR 0x1000 //PORTC^4
#define busy 0x8000 //LCD_DB7
#define busy_dat 0x0080
unsigned char number[10]={'0','1','2','3','4','5','6','7','8','9'};
int a,b,c,d,e,m,n,o,p;
//<<<<<<<<<<<<<<<<<<<<<位置控制<<<<<<<<<<<<<<<<<<<<<<<<<<<<<,
long increment=0, new_place_error=0, set_place=200000; //PI 增量
long summation=0, x_x=0; //纍加值
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.>
//>>>>>>>>>>>>>>>>>>>>速度定義>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
unsigned int adc_new,adc_i,adc_sum,v_top=2500;
unsigned int temp, temp1, temp2,temp3,i_temp=0,sum_temp=0;
//int Kp=3,Ki=5;//Kp=0.464,Ki=0.265;
int now_error=0, old_error=0, speed_i=0, old_speed_i=0;
int set_v, old_set_v;
long increment;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
unsigned int adv_temp,adv_i=0,adv_dsp;
unsigned long adv_sum=0;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
unsigned int C_i=0, C=0, I_now=0; //電機電流顯示定義
int I_er=0, old_I_er=0, I_c=0, max_c=1020, now_pwm, old_pwm;
unsigned int old_temp=0;
unsigned char turn=1;
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int n_duty=0,nkp=22,nki=18;
int i_duty=0,ikp=31,iki=28;
/*8888888888888888888888888888888888888888(AVR中的定義)88888888888
#define lcd_data_port PORTB
#define lcd_data_ddr DDRB
#define lcd_busy_pin PINB
#define lcd_busy_ddr DDRB
#define lcd_control_port PORTD
#define lcd_control_ddr DDRD
#define lcd_RS 0x01
//PORTD^0
#define lcd_RW 0x02
//PORTD^1
#define lcd_EN 0x60
//PORTD^2
#define busy 0x80
//LCD_DB7-PORTB^2
//8888888888888888888888888888888888888888888888888888888888888888888*/
/*----------------------------------函數聲明------------------------------------------*/
void lcd_init_portCD(void);
void lcd_init(void);
void lcd_write_command(unsigned char command,unsigned char wait_en);
void lcd_write_data(unsigned char char_data);
void wait_enable(void);
void lcd_set_xy( unsigned char x, unsigned char y );
void display_a_char(unsigned char x,unsigned char y,unsigned char char_data);
void display_a_string(unsigned char x,unsigned char y,unsigned char *ptr);
void delay(unsigned int i);
void delay_1ms(void );
void delay_nms(unsigned int n) ;
void port_init(void);
void ad_init(void);
void cpu_init(void);
void timer1_init(void);
void timer2_init(void);
void timer3_init(void);
/*****************************************************************
光標命令
lcd_write_command(0x0e,0);//光標開
lcd_write_command(0x0d,0);//光標所在字符閃爍
lcd_write_command(0x0c,0); //光標關
**********************************************************/
/*------------------------------------液晶驅動函數-------------------------------------*/
void lcd_init_portCD(void)
{
lcd_data_port=0xffff; //output high
lcd_data_ddr|=0xff00; //output
lcd_control_port|=0x1C1c;
lcd_control_ddr|=0x1C1c;
}
//液晶初始化
void lcd_init(void)
{
delay_nms(15);
lcd_write_command(0x38,0);//顯示模式設置三次(此時不管lcd空閑與否)
delay_nms(5);
lcd_write_command(0x38,1);
delay_nms(5);
lcd_write_command(0x38,1);
delay_nms(5);
lcd_write_command(0x38,1);//顯示模式設置(從此之后均需lcd空閑)
lcd_write_command(0x08,1);//顯示關閉
lcd_write_command(0x01,1);//顯示清屏
lcd_write_command(0x06,1);//顯示光標移動設置
lcd_write_command(0x0c,1);//顯示開及光標設置
}
//寫指令函數: E=高脈沖 RS=0 RW=0
void lcd_write_command(unsigned char command,unsigned char wait_en)//command為指令,wait_en指定是否要檢測LCD忙信號
{
if(wait_en) wait_enable();//若wait_en為1,則要檢測LCD忙信號,等待其空閑
lcd_control_port&=~lcd_RS_DAT;//RS=0,命令
lcd_control_port&=~lcd_RW_DAT;//RW=0,寫操作
lcd_control_port&=~lcd_EN_DAT;//E=0,下面給LCD一個高脈沖
delay(2);
lcd_data_port=command|0xff00;
delay(2);
lcd_control_port|=lcd_EN_DAT;//E=1
delay(10);
lcd_control_port&=~lcd_EN_DAT;//重設E=0
}
//寫數據函數: E =高脈沖 RS=1 RW=0
void lcd_write_data(unsigned char char_data)
{
wait_enable();//等待LCD空閑
lcd_control_port|=lcd_RS_DAT;//RS=1
lcd_control_port&=~lcd_RW_DAT;//RW=0
lcd_control_port&=~lcd_EN_DAT;//E=0,下面給LCD一個高脈沖
delay(2);
lcd_data_port=char_data|0xff00;
delay(2);
lcd_control_port|=lcd_EN_DAT;//E=1
delay(10);
lcd_control_port&=~lcd_EN_DAT;//重設E=0
}
//正常讀寫操作之前必須檢測LCD控制器狀態:E=1 RS=0 RW=1;DB7: 0 LCD控制器空閑,1 LCD控制器忙。
//檢測忙信號,等待LCD空閑函數
void wait_enable(void)
{
lcd_busy_ddr&=~busy;//設置busy口為輸入
lcd_control_port&=~lcd_RS_DAT;//RS=0
lcd_control_port|=lcd_RW_DAT;//RW=1
lcd_control_port&=~lcd_EN_DAT;//E=0,下面給LCD一個高脈沖
delay(2);
lcd_control_port|=lcd_EN_DAT;//E=1
delay(10);
while(lcd_busy_pin&busy_dat);//等待LCD_DB7為0
delay(2);
lcd_control_port&=~lcd_EN_DAT;//重設E=0
delay(2);
lcd_busy_ddr|=busy;//設置busy口為輸出
}
/**LCD_set_xy:設置LCD顯示的起始位置輸入參數:x、y :
顯示字符串的位置,X:0-15,Y:0-1
LCD第一行顯示寄存器地址:0X80-0X8F
LCD第一行顯示寄存器地址:0XC0-0XCF ***/
void lcd_set_xy( unsigned char x, unsigned char y )
{
unsigned char address;
if (y == 0)
address = 0x80 + x;
else
address = 0xc0 + x;
lcd_write_command(address,1);//一定需要檢查忙信號,所以為1
}
//顯示一個字符函數
void display_a_char(unsigned char x,unsigned char y,unsigned char char_data)//char_data為要顯示的字符
{
lcd_set_xy(x,y);
lcd_write_data(char_data);
}
//指定一行顯示連續字符串:0顯示在第一行,1顯示在第二行,注字符串不能長于16個字符
//顯示一行連續字符串函數
void display_a_string(unsigned char x,unsigned char y,unsigned char *ptr)
{
//ptr:指向無符號字符型變量的指針變量,指針也就是地址,指字符串數組的首指針
lcd_set_xy(x,y);
while(*ptr)//當ptr='\0'(空指針null)跳出循環
{
lcd_write_data(*ptr);//*ptr,指向該地址的內容
ptr++;
}
}
/*---------------------------------------延時函數-------------------------------------*/
void delay(unsigned int i) //第一次6US,以后就是2US一次
{
unsigned int j;
for(j=1;j<i;j++)
{ asm(" nop"); }
}
void delay_nms(unsigned int i) //每一次1MS
{
unsigned int j;
for(j=1;j<=i;j++)
{ delay(456); }
}
void delay_1ms(void)
{
delay_nms(1);
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
/*
void INT_enable();
void INT_disable();
void cpu_init(void) ;
void port_init(void);
void timer2_init(void);
void timer3_init(void);
void timer1_init(void);
void ad_init(void);*/
main()
{
cpu_init();
port_init();
delay_nms(5);
lcd_init_portCD();
delay_nms(5);
lcd_init();
delay_nms(5);
timer1_init();
timer2_init();
timer3_init();
ad_init();
/*display_a_char(0,0,'8');
display_a_char(1,0,'e');
display_a_char(2,0,'t');
display_a_char(3,0,'y'); */
for(;;)
{/*
delay(2); //2.5us delay(10) 7.5us
PADATDIR|=(1<<2);
delay(2);
PADATDIR&=~(1<<2);
*/
// temp = 1234;
a=temp3/1000;
b=temp3%1000/100;
c=temp3%100/10;
d=temp3%10;
display_a_char(0,0,number[a]);
display_a_char(1,0,number[b]);
display_a_char(2,0,number[c]);
display_a_char(3,0,number[d]);
m=adv_temp/1000;
n=adv_temp%1000/100;
o=adv_temp%100/10;
p=adv_temp%10;
display_a_char(7,0,number[m]);
display_a_char(8,0,number[n]);
display_a_char(9,0,number[o]);
display_a_char(10,0,number[p]);
//*****************電流顯示**************
a=C_i/1000;
b=C_i%1000/100;
c=C_i%100/10;
d=C_i%10;
display_a_char(0,1,number[a]);
display_a_char(1,1,number[b]);
display_a_char(2,1,number[c]);
display_a_char(3,1,number[d]);
a=I_c/1000;
b=I_c%1000/100;
c=I_c%100/10;
d=I_c%10;
display_a_char(6,1,number[a]);
display_a_char(7,1,number[b]);
display_a_char(8,1,number[c]);
display_a_char(9,1,number[d]);
delay_nms(500) ;
}
}
//==============I/o初始化=========
//E port as LCD data
//C2 as RS, c3 as R/W, c4 as E
//eva as pwm output
void port_init(void)
{
MCRA=0xfffb; //enable qep and pwm1~6 寫一使能特殊功能,寫0使能I/O功能
//MCRB=0X0000;
MCRC=0x0000;
PCDATDIR=0x1c00; /*高八位是方向,C2~C4口輸出,低八位是數據*/
PEDATDIR=0xff00; /*高八位是方向,E口輸出,低八位是數據*/
// PBDATDIR=0X0000;
// PCDATDIR=0X0000;
// PDDATDIR=0X0000;
PADATDIR|=0X0404; //A2 as output,high
// PEDATDIR&=~(1<<2);
PFDATDIR=0X0000;
}
//=============AD轉換=============
void ad_init(void)
{
EVAIFRA=0XFFFF; //標志位清零
GPTCONA=0X0100; //觸發AD---週期中斷標誌
MAXCONV=0X01; //選擇2個通道
CHSELSEQ1=0X030;//選用通道3&&0
ADCTRL1=0X0900; //ADC控制寄存器1,采樣時間設置,雙排序,啟/停模式
ADCTRL2=0X0500; //用SEQ1,中EVA啟動
}
/*********************************/
//=========中斷開關=======
void INT_enable()
{
asm(" clrc INTM"); //中斷允許
}
void INT_disable()
{
asm(" setc INTM"); //中斷禁止
}
/******************************/
//===========CPU初始化===========
void cpu_init(void)
{
asm(" setc SXM"); //符號位擴展有效
asm(" clrc OVM"); //累加器中結果正常溢出
asm(" clrc CNF"); //B0被配置成數據存儲空間
INT_enable(); //開中斷
SCSR1=0X02FE; //2倍頻,15MHz*2=30MHz
WDCR=0X00E8; //禁止看門狗
IMR=0x0003; //中斷設置
IFR=0XFFFF; //清除中斷標志位:寫1清除
WSGR &= 0xf800; //禁止所有等待狀態
}
//==========定時器1初始化程序===============PWM
void timer1_init(void)
{
//EVAIMRA=EVAIMRA|0x0080; //允許timer1的周期中斷
//EVAIFRA=EVAIFRA&0X0080; //清除定時器1周期中斷標志
T1CON=0X1046; //timer1為連續增計數,不分頻,內部時鐘,
COMCONA=0Xa600; //周期重裝
CAPCONA = 0xe000; // 使能QEP
ACTRA=0X0001; //PWM1高有效
T1PR=1024; //比較上限值,時鐘頻率30MHz,開關頻率29KHz
CMPR1=10; //比較初值
//CMPR2=500;
// CMPR3=900;
T1CNT=0; //TIMER1計數器清零
}
/*************************************/
//=============TIMER2_INIT=============QEP
void timer2_init(void)
{
T2PR=0xffff; //定時器最大值
T2CON=0X1870; //定向增/減計數,使能QEP
T2CNT=0; //計數器出始值為0
// EVAIMRB|=0X0001; //允許中斷
}
/*************************************/
/*************************************/
void timer3_init()
{
// T3PR=937; //定時1MS
T3PR=1875; //定時2MS
T3CON=0X1540; //增計數
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -