Ccs c for pic16F877a mục lục I. Tổng quan về ccs vì sao ta sử dung ccs ?



tải về 1.15 Mb.
trang10/15
Chuyển đổi dữ liệu23.08.2016
Kích1.15 Mb.
#26977
1   ...   7   8   9   10   11   12   13   14   15

8.7. 16f877a_8x16_2mau

//+===Chuong trinh LED matrix display===========+

//| Thiet ke: Nguyen Chi Linh - DT8K47 - DHBKHN |

//| MCU: PIC16F877a (16K FLASH ROM, 256B EEPROM) |

//| Cac IC khac: 74154 - demux/decoder 1-of-16 |

//| 74595 - Ghi dich 8bit |

//+=============================================+

#include <16f877a.h>

#include

#device *=16 ADC=8

#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT

#use delay(clock=20000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
// Dinh nghia cac chan cho ket noi 74595

#define clk RD1 //RD1

#define data RD0 //RD0

#define latch RD2 //RD2

#define data_h PORTB // Du lieu hang

#define decode_c PORTD // Giai ma cot


// Bo nho dem man hinh hien thi

int8 buff_disp[64]; //Bo nho dem cho man hinh LED

int8 max_char=118; //SO ky tu hien thi toi da

int8 time=5; //Bien quy dinh toc do chu chay

int1 text_on_rom=0,stop=0;

int8 chon=3;

int8 address;

int8 choose_text = 0;

int1 Buffer_Screen_Full;

int8 Num_Byte_Buffer=0;

#define BUFFER_SIZE 32

BYTE sbuffer[BUFFER_SIZE];

BYTE next_in = 0;

BYTE next_out = 0;

//=========KHAI BAO CAC CHUONH TRINH CON================

int8 doc_eeprom(int8 addr);

void send_64(int32 High_Byte,int32 LowByte);

void display();

void copy_2_ram1(int8 index_char);

void copy_2_ram2(int8 index_char);

void update_eeprom();

void convert_bcd(int8 x);


#include //File chua bo font ma hoa ky tu ASCII

#include

//============Chuong trinh phuc vu ngat=====================

#int_rda


void serial_isr() {

int t;
sbuffer[next_in]=getc();

t=next_in;

next_in=(next_in+1) % BUFFER_SIZE;

if(next_in==next_out)

next_in=t; // Buffer full !!

}

//===========Chuong trinh chinh================



void main()

{

int8 i,num_char,ascii_code,k;



#bit update_rom = 0x05.5
char const a[119]= " Hello World.LED Matrix PIC16F877A - ULN2803 - 74HC595. Bang thong tin dien tu. ^-^Nguyen Chi Linh-DT8 DAI HOC BKHN^-^";

char const b[119]= " HAPPY NEW YEAR *2006* - CHUC MUNG NAM MOI - Chuc Mung Nam Moi - Happy new year. linhnc308@yahoo.com 1234567890 ";

char const c[119]= " You like a little flame in my heart. When I see ou, the flame is like up. Because I love you. Because I LOVE YOU ";

char const d[119]= " Do an mon: Thiet Ke Mach Logic - GVHD: Nguyen Nam Quan. Nhom sinh vien: Nguyen Chi Linh - Tek Song Leng. Lop Dien Tu8";

char const e[119]= " ABCDEFGHIJKLMNOPQRSTUVWXYZ - abcdefghijklmnopqrstuvwxyz - 1234567890 - ~!@#$%^&*()_+*/><:?., linhnc308@yahoo.com ";

char const adc[6] = " ADC=";

//===========================================

TRISA = 1;

TRISB = 0; // Thiet lap chan vao ra

TRISD = 0;

TRISE = 0;

PORT_B_PULLUPS(TRUE);

PORTE = 0xFF;

//==Thiet lap ngat ngoai 0 ==================

// enable_interrupts(global);

// enable_interrupts(int_rda);

//===========================================

setup_adc_ports(AN0); //Chon kenh AN4 nhung ko hieu sao can them phan khai bao

setup_adc(ADC_CLOCK_INTERNAL);// ben duoi dechon dung kenh AN4 cho no chay dung

delay_ms(10);

//======= HIEN THI TRAI TIM =======

//======= HIEN THI BAN TIN ========

for(i=0;i<6;++i)

write_eeprom(0xf0+i,adc[i]);

for(i=0;i<118;++i)

write_eeprom(i,a[i]);

write_eeprom(0xff,max_char); // Luu so ky tu toi da vao ROM

//if(update_rom==1) //Kiem tra cong tac cap nhat du lieu

// update_eeprom(); //Goi chuong trinh con cap nhat(giao tiep qua cong COM)

hien_thi:

for (i=0;i<=64;i++) // Clear RAM of buff_disp

buff_disp[i]=0xff;

//Doanchuong trinh nay se hien thi noi dung ban tin luu trong EEPROM

address = label_address(hien_thi);

num_char=0;ascii_code=0;

while(1) {


for (num_char=0;num_char < max_char;++num_char) // Hien thi chu tren man hinh

{

/* if(choose_text==0) {choose_text=1; goto hien_thi;} // Xem xet viec cap nhat hien thi



if(text_on_rom==0)

{

switch(chon)



{

case 0: j=a[i]-32; break;

case 1: j=b[i]-32; break;

case 2: j=c[i]-32; break;

case 3: j=d[i]-32; break;

case 4: j=e[i]-32; break;

case 5: chon=0; break;

}

}



else

j=read_eeprom(i)-32;

*/

ascii_code = a[num_char] - 32;



if(ascii_code < 51)

copy_2_ram1(ascii_code);

else

{

ascii_code = ascii_code - 51;



copy_2_ram2(ascii_code);

}

}



// Ket thuc hient hi TEXT

/* k=read_adc();

convert_bcd(k);

for(i=0;i<8;++i) // Hien thi gia tri doc dc tu ADC

{

k = doc_eeprom(0xf0 + i)-32;



copy_2_ram1(k);

}

*/



}

}

//========= END MAIN ==============



// === CAC CHUONG TRINH CON =========

/*

void send_8(int8 byte_shift) {



int8 i,temp;

#bit MSB = temp.7;

temp = byte_shift;

for(i = 0;i < 8; ++i)

{

data = MSB;



clk=1;

shift_left(&temp,1,0);

clk=0;

}

// latch=1; //Chot du lieu



// latch=0;

}

// == Send data to 64 Colum ==



void send_64(int32 ByteH,int32 ByteL) {

int8 i;


int8 Bytesend[8];
Bytesend[7] = Make8(ByteH,3);

Bytesend[6] = Make8(ByteH,2);

Bytesend[5] = Make8(ByteH,1);

Bytesend[4] = Make8(ByteH,0);

Bytesend[3] = Make8(ByteL,3);

Bytesend[2] = Make8(ByteL,2);

Bytesend[1] = Make8(ByteL,1);

Bytesend[0] = Make8(ByteL,0);


clk = latch = 0;

for(i = 7;i >=0 ; --i)

{

send_8(Bytesend[i]);



}

latch=1; //Chot du lieu

latch=0;

}
*/

void send_64(int32 ByteH,int32 ByteL) {

int8 i;


#bit LSB_bit = ByteH.0;
for(i = 0;i < 64 ; ++i)

{

data = bit_test(ByteH,31); // 1 chu ky xung Clock la ~3.2uS



clk=1;

shift_left(&ByteL,4,0);

shift_left(&ByteH,4,0);

LSB_bit = bit_test(ByteL,31);

clk=0;

}

latch=1; //Chot du lieu



latch=0;
}

//===========Chuong trinh con hien thi=========

void display() {

int8 count;

int32 Colum_L=0,Colum_H=0;

int8 i;


#bit bit0_Of_ColumH = Colum_H.0;
time = read_adc()/10; // Viec doc gia tri ADC truoc khi hien thi lam cho viec thay doi

// toc do chu chay linh hoat hon, truc tiep tha doi

for (i=0;i<=time;i++) //Toc do chu chay thay doi boi bien time

{

//Colum_L = 1; //Bien dem so cot, xem da quet het 16 cot chua



//Colum_H = 0;

bit_set(Colum_L,0);

for(count=64;count>0;count--)

{

send_64(Colum_L,Colum_H);



PORTB = buff_disp[count];

shift_left(&Colum_L,4,0);

shift_left(&Colum_H,4,0);

bit0_Of_ColumH = bit_test(Colum_L,31);

delay_us(150);

PORTB = 0xFF;

}

}

}



//========Copy to Ram1=====================

void copy_2_ram1(int8 index_char) {

int8 i,j;
for (j=0;j<=5;j++)

{

if ((stop==1) && (Buffer_Screen_Full==1))



{

display(); // Call display() function, no shift text on screen

}

else


{

for (i=64;i>0;i--)

buff_disp[i]= buff_disp[i-1]; // Dich RAM sang trai >> Tao hieu ung chu chay

buff_disp[0]= font[index_char].b[j]; // Luu ma ascii vao RAM man hinh

Num_Byte_Buffer++; // Count Number of byte are loaded to buffer

if ((stop == 1) && (Num_Byte_Buffer == 63))

{

Num_Byte_Buffer = 0;



Buffer_Screen_Full = 1;

}

else



Buffer_Screen_Full = 0;

display(); // Goi hien thi

}

}

buff_disp[0]=0xff;



}

//========Copy to Ram 2===================

void copy_2_ram2(int8 index_char) {

int8 i,j;


for (j=0;j<=5;j++)

{

if ((stop==1) && (Buffer_Screen_Full==1))



{

display(); // Call display() function, no shift text on screen

}

else


{

for (i=64;i>0;i--)

buff_disp[i]= buff_disp[i-1]; // Dich RAM sang trai >> Tao hieu ung chu chay

buff_disp[0]= font2[index_char].b[j]; // Luu ma ascii vao RAM man hinh

Num_Byte_Buffer++; // Count Number of byte are loaded to buffer

if ((stop == 1) && (Num_Byte_Buffer == 63))

{

Num_Byte_Buffer = 0;



Buffer_Screen_Full = 1;

}

else



Buffer_Screen_Full = 0;

display(); // Goi hien thi

}

}

buff_disp[0]=0xff; // Them mot khoang trang giua hai ky tu



}

//=========Update EEPROM===================

void update_eeprom() {

byte i,j,addr,max;

char temp;

char string[64];

// Hien thi noi dung cua EEPROM

printf("\r\n256 byte EEPROM of PIC16F88:\r\n"); // Display contents of the first 64

for(i=0; i<=15; ++i) // bytes of the data EEPROM in hex

{

for(j=0; j<=15; ++j)



printf( "%2x ", doc_eeprom( i*16+j ) );

printf("\n\r");

}

// Hien thi noi dung ban tin



i=0;

do

{



temp = doc_eeprom(i);

printf( "%C", temp);

i++;

} while (temp != 0xff);



//--------Ket thuc ----------

printf("\r\nTong so chu: %2u", doc_eeprom(0xff));

printf("\r\n\nCo thay doi ban tin ko(Y/N)? "); temp=getc();//temp = getc();

if (temp == 'y' || temp == 'Y')

{

printf("\r\nSo chu hien thi moi la: ");



max_char=gethex();

write_eeprom(0xff,max_char);

printf("\r\nDia chi EEPROM can thay doi: ");

addr = gethex();

if (addr >= max_char)

write_eeprom(0xff,addr);

printf("\r\nSo ky tu them vao: ");

max = gethex(); // Tra ve gia tri Hexa

if(max >= max_char)

write_eeprom(0xff,max); // Cap nhat so ky tu

printf("\r\nNew: ");

get_string(string,max+1);

for (i=0;i

{

write_eeprom(addr,string[i]);



addr=addr+1;

}

text_on_rom=1;



}

else


{

printf("Tro ve !"); // Ket thuc viec cap nhat, tro ve hien thi

text_on_rom = 0;

}

}



//=============READ EEPROM=====================

int8 doc_eeprom(int8 addr)

{

EEADR=addr;



RD=1;

return(EEDATA);

}

//=======Chuyen gia tri hex ra so ASCII=========



void convert_bcd(int8 x)

{

int8 temp;



int8 a;

temp=x%10; //chia lay phan du, so hang don vi

write_eeprom(0xf7,temp+0x30); //Cong them 0x30 de tra ve gia tri SCII

a=x/10; //tach hang tram va hang chuc

temp=a%10; //tach so hang chuc

write_eeprom(0xf6,temp+0x30);

temp=x/100;

write_eeprom(0xf5,temp+0x30);

}

9. Động cơ

Mình đang thử ctr điều khiển động cơ: Khi có tín hiệu từ chân RB0 thì động cỏ quay, nếu đang quay mà có tín hiệu từ RB1 thì động cơ quay ngược lại bằng thời gian no đã quay xuôi, bạn nào có thể viết cho mình một ví dụ như vậy bằng CCS được ko, cảm ơn nhiều.

Bạn có thể dùng ngắt ngoài để điều khiển cái động cơ của bạn:

9.1. DC Motor

9.1.1. code

#include <16F877A.h>

#device *=16

#device adc=8

#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT

#use delay(clock=20000000)



--code.C

#include <16f877a.h>

#include

#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT

#use delay(clock=20000000)

#include


#define PWMEn1 TRISC2

#define PWMEn2 TRISC1

#define INTS_PER_SECOND1 19
#define Set_value 35

int8 int_count1;

int16 so_vong,count;

void DispLine1(int8 pos,int16 POSCNT);

void DispLine2(int8 pos,int16 POSCNT);
#int_rtcc // Ngat Timer 0

void Timer0_isr() // Dem so vong quay dong co

{

count++;


}

#INT_TIMER1 // Chuong trinh ngat Timer 1

void Timer11_isr() { // Ham duoc goi khi TImer1 tran (65535->0)

// Xap xi 19 lan / giay

if(--int_count1==0)

{

int_count1 = INTS_PER_SECOND1;



so_vong = (count*255 + get_timer0())/14;

count = 0;

set_timer0(0);

}

}



void main() {

int16 value,current;

int1 OutOfRange = 0;
TRISD = 0;

TRISB = 0xF0;


lcd_init();

printf(lcd_putchar,"DC Motor Control");

setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM

// The cycle time will be (1/clock)*4*t2div*(period+1)

// In this program clock=20000000 and period=127 (below)

// For the three possible selections the cycle time is:

// (1/20000000)*4*2*128 = 51.2 us or 19.5 khz

// (1/10000000)*4*1*128 = 51.2 us or 19.5 khz

// (1/10000000)*4*4*128 = 204.8 us or 4.9 khz

// (1/10000000)*4*16*128= 819.2 us or 1.2 khz

// set frequency

//setup_timer_2(T2_DIV_BY_1, 31, 1); //78.12KHz

//setup_timer_2(T2_DIV_BY_1, 46, 1); //208.3KHz

//setup_timer_2(T2_DIV_BY_1, 255, 1); //19.53KHz value = 0..1023

//setup_timer_2(T2_DIV_BY_4, 255, 1); //4.5KHz

setup_timer_2(T2_DIV_BY_16, 255, 16); //1.2KHz

//===================================

setup_timer_0 (RTCC_DIV_1|RTCC_EXT_H_TO_L);

set_timer0(0);

set_timer1(0);

setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);

enable_interrupts(INT_RTCC);

enable_interrupts(INT_TIMER1);

enable_interrupts(GLOBAL);


count = 0;

int_count1 = INTS_PER_SECOND1;


setup_adc(adc_clock_internal);

set_adc_channel( 0 );delay_ms(10);


PWMEn1 = 0;

TRISA = 0xFF;

TRISC = 0;

RD2 = 1;
value=1023;

set_pwm1_duty(value);

current = value;

lcd_putcmd(1);

lcd_putcmd(0x80);

Printf(lcd_putchar,"D=");
while( TRUE ) {

DispLine1(2,value);

DispLine2(0,so_vong);

if (so_vong > Set_value) // Error Point 1 - Down

{

value = value - (so_vong-Set_Value);



OutOfRange = 0;

lcd_putcmd(0x87);

lcd_putchar(" ");

}

if (!OutOfRange)



{

if (so_vong < Set_value) // Error Point 2 - Up

value = value + (Set_Value-so_vong);

if (value > 1024)

{

value = 1023;



lcd_putcmd(0x87);

lcd_putchar("E");

OutOfRange = 1;

}

}



set_pwm1_duty(value);

}

}



void DispLine1(int8 pos,int16 POSCNT)

{

int8 chuc,donvi;



int32 temp;

temp = ((int32)POSCNT*100)/1023;

chuc = temp / 10;

donvi = temp % 10;

lcd_putcmd(0x80 + pos);

lcd_putchar(chuc + 0x30);

lcd_putchar(donvi + 0x30);

lcd_putchar("%");

}

void DispLine2(int8 pos,int16 POSCNT)



{

int8 chucnghin,nghin,tram,chuc,donvi;

int16 temp;

temp = POSCNT;

// chucnghin = temp / 10000;

// temp = temp % 10000;

nghin = temp / 1000;

temp = temp % 1000;

tram = temp / 100;

temp = temp % 100;

chuc = temp / 10;

donvi = temp % 10;

lcd_putcmd(0xC0 + pos);

//lcd_putchar(chucnghin + 0x30);

lcd_putchar(nghin + 0x30);

lcd_putchar(tram + 0x30);

lcd_putchar(chuc + 0x30);

lcd_putchar(donvi + 0x30);

Printf(lcd_putchar,"V/S");

}

9.1.2. Position_Control

//

// The following code uses the C-18 compiler and a PIC18F4331 at 40MHz (Phase lock looped 10MHz oscillator (PLL))



// It demonstrates TOGGLING PIN 7 OF PORT B AT 25Hz (200Hz WITH 1:8 PRESCALE) using timer0

// on the PIC18F4331.

//

// The following files should be included in the MPLAB project:



//

// -- Main source code file

// p18f4331.lkr -- Linker script file

//

// The following project files are included by the linker script:



//

// c018i.o -- C startup code

// clib.lib -- Math and function libraries

// p18f4331.lib -- Processor library

//

//---------------------------------------------------------------------



#include
// Register definitions

//#include


// Register definitions

#include

#include

#include

#include // I2C library functions

#include


// PWM library functions

#include // ADC library functions

#include
// PORTB library function

#include // Timer library functions

#include // USART library functions

#include /* for 'Delay10KTCYx' */


//---------------------------------------------------------------------

// Configuration bits

//---------------------------------------------------------------------

//

//// DO NOT PUT COMMENTS INSIDE ANY PRAGMA



//// Programs the pic configuration registers

#pragma romdata CONFIG

_CONFIG_DECL(_CONFIG1H_DEFAULT & _OSC_HSPLL_1H,

_CONFIG2L_DEFAULT & _BOREN_ON_2L & _PWRTEN_ON_2L,

_CONFIG2H_DEFAULT & _WDTEN_OFF_2H,

_CONFIG3L_DEFAULT,

_CONFIG3H_DEFAULT & _MCLRE_ON_3H ,

_CONFIG4L_DEFAULT & _LVP_OFF_4L & _STVREN_OFF_4L,

_CONFIG5L_DEFAULT,

_CONFIG5H_DEFAULT,

_CONFIG6L_DEFAULT,

_CONFIG6H_DEFAULT,

_CONFIG7L_DEFAULT,

_CONFIG7H_DEFAULT);

#pragma romdata
//& _BKBUG_OFF_4L
//---------------------------------------------------------------------

//Constant Definitions

//---------------------------------------------------------------------

//#define TIME 3 // Array index for segment delay time

//#define INDEX PORTBbits.RB0 // Input for encoder index pulse

#define TRUE 1

//#define INPUT 1

#define OUTPUT 0


//ENCODER INITIALIZATION POSITION

#define ENCDR_START_H 0x7F //b'01111111' ; THIS IS 0X7F

#define ENCDR_START_L 0xFF
#define ASCII_NUM_OFFSET 48
#define BAUD_9600 64 // for 40MHz (PLL x 10.00 MHz crystal)

// and set USART_BRGH_LOW

#define BAUD_19200 129 // and set USART_BRGH_HIGH

#define BAUD_57600 42 // and set USART_BRGH_HIGH

// USART_BRGH_HIGH and 64, for 9600 baud @ 10MHz (0.16% ERROR IN RATE)

// USART_BRGH_LOW and 64, for 9600 baud @ 40MHz (0.16% ERROR IN RATE)

// USART_BRGH_HIGH and 129, for 19200 baud @ 40MHz

//** // BRG16_HIGH, USART_BRGH_HIGH and 172, for 57,600 baud @ 40MHz (.35% ERROR IN RATE)

// USART_BRGH_HIGH and 42, for 57,600 baud @ 40MHz (.94% ERROR IN RATE)
// DEFINE TIMER INTERRUPT RATE FOR SERVO LOOP, ETC... (e.g. WRITING ACCELEROMETER DATA TO RS-232)

#define TMR0_HIGH_BYTE 0xCF //;0xEC ;Load TMR0 with the value for 250 Hz THIS WAS FOR TIMER 1

#define TMR0_LOW_BYTE 0x2C //;0x78

// ;set the timer for 0xF63C = 63,036 = 2^16 - 2,500 steps, since 2,500 x 1/2.5^6 = 1 milisecond

// ;0xFB1E FOR 2000Hz (FOR 10MHz CRYSTAL /4)

// ;0xF63C FOR 1000Hz (FOR 10MHz CRYSTAL /4)

// ;0xEC78 FOR 500Hz (FOR 10MHz CRYSTAL /4)

// ;0xCF2C FOR 200Hz? (FOR 10MHz CRYSTAL /4)

// ;0x9E58 FOR 100Hz (FOR 10MHz CRYSTAL /4)

// ;0x3CB0 FOR 50Hz (FOR 10MHz CRYSTAL /4) 200hz

// ;0x0BDC for 40 Hz (FOR 10MHz CRYSTAL /4)

// ;FORMULA IS PERIOD/ TICK_TIME = STEPS, THEN 2^16 - STEPS

// ;WHERE TICK TIME IS 1/(CRYSTAL SPEED/4)

// 2^16 = 65536

//0x3CB0 = 15536 FOR 200Hz (FOR 40MHz Clock)

//0xB1E0 = 45536 FOR 500Hz (FOR 40MHz Clock)

//0xD8F0 = 55536 FOR 1,000Hz (FOR 40MHz Clock)

//0xF830 = 63536 FOR 5,000Hz (FOR 40MHz Clock)

//0xFC18 = 64536 FOR 10,000Hz (FOR 40MHz Clock)

//0xFE70 = 65136 FOR 10,000Hz (FOR 40MHz Clock)

//---------------------------

// Defines by Li Jiang

//------------------------
#define STEP_90 3396; // 3396 is 90 degree.

#define STEP_80 3019;

#define STEP_70 2641;

#define STEP_60 2264;

#define STEP_50 1887;

#define STEP_40 1509;

#define STEP_30 1132;

#define STEP_20 755;

#define STEP_10 377;
#define STEP_COUNTS 200;
static int STEP;

// Variable defined by Li


static unsigned int x, x_old;

static long int error, integError_old,integError, Kp, Ki, Kd; //these should be signed


static long double vel, vel_old, control; //these should also be signed

static int xDes;

int Portb_Data;

int Step_Flag = 0;

int Step_Data[80];
int old_control=0;

int Step_Count = 1;

int Torque_Flag = 0;

int Torque_Control=0;


int STEP_Mount = 0;
int Torque_Step = 0;
int STEPS = 0;

//---------------------------------------------------------------------

// Variable declarations

//---------------------------------------------------------------------

unsigned char str[7], charNumber;

unsigned int result;

// int hundreds, tens, tens, ones, remainder;
unsigned int number, number1, number2;

int readBuffer = 0;

//unsigned char TRUE = 1;

union


{

struct


{

unsigned Timeout:1; //flag to indicate a TMR0 timeout

unsigned None:7;

} Bit;


unsigned char Byte;

} Flags;
//---------------------------------------------------------------------

// Function Prototypes

//---------------------------------------------------------------------

void Setup(void); // Configures peripherals and variables

// Writes a string from ROM to the USART

void putrsUSARTWill(const rom char *data);

void WriteUSARTWill(char data);

void SendRS232Int(unsigned int data);

void SendRS232Char(char data);

unsigned int simpleAnalog(void);

void PWM14out(unsigned int result);


void InterruptHandlerHigh (void);

void PID_Init(void);

void PID_Control(void);

void SendRS232NUM(long int);

unsigned int simpleAnalog1(void);

//---------------------------------------------------------------------

// Setup() initializes program variables and peripheral registers

//---------------------------------------------------------------------

void Setup(void)

{

EnablePullups(); // Enable PORTB pullups


//SETUP port A for analog input and QUADRATURE ENCODER READ CAPABILITY

TRISA = 0b11111011; //0xF8 This is b'11111000' 0=output, 1=input


TRISB = OUTPUT; //0;

PORTB = 0b11111110;


TRISC = 0b10000000; //; // 0=output, 1=input

// SETUP SO THAT THE RX PIN IS AN INPUT

// --------------------------------------------------------------

// FROM INTERRUPT CODE FROM MICROCHIP (timer 0 and interrupt settings)

Flags.Byte = 0;

INTCON = 0x20; //= 00100000 //disable global and enable TMR0 interrupt

INTCON2 = 0x84; //= 10000100 //TMR0 high priority

RCONbits.IPEN = 1; //enable priority levels


TMR0L = TMR0_LOW_BYTE; //INITIALIZE timer 0

TMR0H = TMR0_HIGH_BYTE; //INITIALIZE timer 0

// T0CON = 0x82; // =0b10000010 //set up timer0 - prescaler 1:8

// T0CON = 0b10000001; // =0b10000010 //set up timer0 - prescaler 1:4

T0CON = 0b10001000; //set up timer0 - with no prescaler

INTCONbits.GIEH = 1; //enable interrupts

//for timer 1

// ;FOR CALCULATING INTERGRAL TERM AND VELOCITY TERM (ADD IN SOMETHING TO READ THE ENCODER TOO

// bsf IPR1,TMR1IP ;set Timer1 as a high priority interrupt source

// bcf PIR1,TMR1IF ;clear the Timer1 interrupt flag

// bsf PIE1,TMR1IE ;enable Timer1 interrupts
// MOVLW b'00110000' ;PRESCALER = 1:8

// T1CON = 0b10001000; //set up timer0 - with no prescaler

// movlw timer1Hi ;reload T1 registers with constant time count (user defined)

// movwf TMR1H

// movlw timer1Lo

// movwf TMR1L

// bsf T1CON,TMR1ON ;turn on Timer1
//configure USART (CLOCK DEPENDENT)

// baudUSART(BAUD_16_BIT_RATE); THIS DOESN'T CURRENTLY WORK

// 0b00001000); //USE THIS IF WE NEED TO SET BRG16_HIGH FOR BAUD RATE GENERATOR (SEE p. 224)

//BAUDCTL = BAUDCTL |

//THIS DOESN'T WORK EITHER

//_asm


// MOVLW B'01001010' ; SETTING Baud rate WITH 16 BIT BRGH and 10MHz crystal

// MOVWF BAUDCTL ; SEE P. 171 IN DATASHEET

//_endasm

OpenUSART( USART_TX_INT_OFF &

USART_RX_INT_OFF &

USART_ASYNCH_MODE &

USART_EIGHT_BIT &

USART_CONT_RX &

USART_BRGH_HIGH,

BAUD_19200 ); // USART_BRGH_HIGH and 64, for 9600 baud @ 10MHz (0.16% ERROR IN RATE)

// USART_BRGH_LOW and 64, for 9600 baud @ 40MHz (0.16% ERROR IN RATE)

// USART_BRGH_HIGH and 129, for 19200 baud @ 40MHz

//** // BRG16_HIGH, USART_BRGH_HIGH and 172, for 57,600 baud @ 40MHz (.35% ERROR IN RATE)

// USART_BRGH_HIGH and 42, for 57,600 baud @ 40MHz (.94% ERROR IN RATE)


RCSTA = 0b10010000; //SETTING RECEIVE AND CONTROL REG (SEE P. 167 IN DATASHEET)
WriteUSART(13); //carriage return //0x41=A, 0x48=H

putrsUSARTWill("PIC18F4331 DC Servomotor");


//putrsUSART(ready);

//SETUP QUADRATURE ENCODER READ CAPABILITY

QEICON = 0x98; // = B'10011000' (see p 171)

// MOVLW B'00000000' // DIGITAL FILTER CONTROL REGISTER (see p 178)

DFLTCON = 0x00; //FILTER INPUTS A & B

//INITIALIZE ENCODER COUNT to center of 16-bit range

POSCNTH = ENCDR_START_H; // High byte of 16-bit encoder count

POSCNTL = ENCDR_START_L; // low byte

// A/D SETUP (ADCON2 CLOCK DEPENDENT)

// can also use OpenADC( ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_8ANA_0REF, ADC_CH0 & ADC_INT_OFF) //(WON'T WORK FOR PICF4331)

// ADCON0: A/D CONTROL REGISTER 0 (USE TO SAMPLE SINGLY, SEQUENTIALLY, OR SIMULTANEOUSLY

ADCON0 = 1; // = B'00000001' ; set up, but don't start conversion on analog input A0 (see p 181 in datasheet)

//to turn off A/D make LSB low ; SET FOR Fosc/8 conversion time

// ADCON1: A/D CONTROL REGISTER 1 (SET Vref AND A/D CONVERSION BUFFER OPTIONS (WILL STORE UP TO 4 A/D READINGS IN BUFFER)

ADCON1 = 0; // = B'00000000' (see p 245 in datasheet) // SET FOR Fosc/32 conversion time ;right justified

// use B'00010000' ; for 4 buffer LOCATIONS ; (see p 245 in datasheet)

// ADCON2 – A/D CONTROL REGISTER 2 (JUSTIFICATION AND ACQUISITION & CONVERSION TIMING

ADCON2 = 0b10001010; //40MHz right justified, (2 * T_AD) aquisition time, t_osc*32 acquisition time (see p 246 in datasheet)

// = B'10000001' //10MHz ; right justified, 0 T_AD aquisition time, t_osc/8 acquisition time (see p 246 in datasheet)

// USE B'10000011' //8MHZ ; right justified, 0 T_AD aquisition time, t_osc/4 acquisition time (see p 246 in datasheet)

// = B'10000001' //10MHz ; right justified, 0 T_AD aquisition time, t_osc/8 acquisition time (see p 246 in datasheet)

// ADCON3: A/D CONTROL REGISTER 3 (INTERRUPTS AND TRIGGER SOURCES)

ADCON3 = 0xC0; // = B'11000000' //no interrupts (see p 247 in datasheet)

// ADCHS: A/D CHANNEL SELECT REGISTER (FOR PINS WHERE THERE ARE 2 ALTERNATIVES FOR A PARTICULAR ANALOG INPUT PIN)

ADCHS = 0; //SET GROUP PINS FOR ACQUISITION SEQUENCES(see p 248)

// ANSEL0: ANALOG SELECT REGISTER 0 (SET A PARTICULAR PIN AS ANALOG INPUT BY MAKING PIN# = 1, ELSE DIG. IN)

ANSEL0 = 0b00000011; // = B'00000001'; // SET PIN 0 AS ANALOG, ALL OTHERS DIGITAL, // SELECT WHICH PINS ARE ANALOG VS. DIGITAL (see p 249)

// can also use SetChanADC(ADC_CH_0); //to change which channel is sampled (WON'T WORK FOR PICF4331)

//ANSEL1: ANALOG SELECT REGISTER 1(IF YOU WANT TO USE PIN AN8 FOR ANALOG IN)

ANSEL1 = 0; // = B'00000000'

//*****************************************************************/

// PWM SETUP FOR POWER PWM PINS (PORTS B & D) (LOOSELY CLOCK DEPENDENT)

// PWM Timer Control register 0 (PTCON0)

PTCON0 = 0;

// PWM Timer Control register 1 (PTCON1)

PTCON1 = 0x80; // = 0b10000000

// PWM Control register 0 (PWMCON0)

PWMCON0 = 0x6F; // = B'01101111' CONFIGURED FOR PWM PINS 1 AND 3 TO OUTPUT

// B'01011111' to CONFIGURE FOR ALL PWM PINS TO OUTPUT

// PWM Control register 1 (PWMCON1)

PWMCON1 = 0;

// PWM Period Registers (PTPERH and PTPERL)

PTPERH = 0x00; //0x03 FOR 12 BIT DUTY CYCLE RESOLUTION, 0x0F FOR 14 BIT

PTPERL = 0xFF;

//ENABLE WRITE TO PWM REGISTER

// BSF pidStat2, pwm_enable

// BSF PORTB, 6 ; INDICATE THAT PWM IS ENABLED BY LIGHTING LED B6

//DISABLE WRITE TO PWM REGISTER

// BCF pidStat2, pwm_enable

// BCF PORTB, 6 ; INDICATE THAT PWM IS disABLED BY LIGHTING LED B6


} //end of setup
//---------------------------------------------------------------------

// main()

//---------------------------------------------------------------------
void main(void)

{

// unsigned char str[7];



//int readBuffer = 0;
Setup(); // Setup peripherals and software
PID_Init();
while(TRUE)

{

//TOGGLE PIN B7 TO MONITOR LOOP TIME SEE JUST HOW FAST THIS LOOP CAN COMPLETE



// PORTBbits.RB7 = ~PORTBbits.RB7;
// ClrWdt(); // Clear the WDT
//--- READING FROM SERIAL PORT

//Is data available in the read buffer?

//while (!DataRdyUSART());

//

//Read a fixed-length string of characters from the specified USART.



//char inputstr[10];

//getsUSART( inputstr, 5 );

//

//Read a byte (one character) out of the USART receive buffer, including the 9th bit if enabled.



//int result;

//result = ReadUSART();

//result |= (unsigned int)
//WriteUSARTWill(55);
if(DataRdyUSART())

{

readBuffer = ReadUSART(); //read ASCII value of key pressed on keyboard



PORTBbits.RB5 = ~PORTBbits.RB5; //toggle pin 5 if receive register being read

WriteUSARTWill(readBuffer); //echo value to RS-232

//*************** STEP ***********************

// if (readBuffer =='z')

// {

// Torque_Control += 10;



// }

//

// if (readBuffer =='x')



// {

// Torque_Control -= 10;

// }

// if (readBuffer =='c')



// {

// Torque_Control += 1;

// }

//

// if (readBuffer =='v')



// {

// Torque_Control -= 1;

// }

//

// if (readBuffer =='t')



// {

//

// putrsUSARTWill("Torque Step");



// WriteUSARTWill(13);

// Torque_Step = 1;

// }

//

// if (readBuffer =='y')



// {

// Torque_Step = 0;

// }
if (readBuffer =='k')

{

Torque_Flag = 1;



}

if (readBuffer =='l')

{
Torque_Flag = 0;

xDes = x;

}
if (readBuffer =='1')

{

STEP_Mount = STEP_10; STEPS =10;



}
if (readBuffer =='2')

{

STEP_Mount = STEP_20; STEPS =20;



}
if (readBuffer =='3')

{

STEP_Mount = STEP_30; STEPS =30;



}
if (readBuffer =='4')

{

STEP_Mount = STEP_40; STEPS =40;



}

if (readBuffer =='5')

{

STEP_Mount = STEP_50; STEPS =50;



}

if (readBuffer =='6')

{

STEP_Mount = STEP_60; STEPS =60;



}

if (readBuffer =='7')

{

STEP_Mount = STEP_70; STEPS =70;



}

if (readBuffer =='8')

{

STEP_Mount = STEP_80; STEPS =80;



}

if (readBuffer =='9')

{

STEP_Mount = STEP_90; STEPS =90;



}

if (readBuffer =='0')

{

STEP_Mount = 0; STEPS =0;



}
if (readBuffer =='q')

{

STEP_Mount += 38; STEPS +=1;



}
if (readBuffer =='w')

{

STEP_Mount += 75; STEPS +=2;



}
if (readBuffer =='e')

{

STEP_Mount += 113; STEPS +=3;



}
if (readBuffer =='r')

{

STEP_Mount += 151; STEPS +=4;



}

if (readBuffer =='t')

{

STEP_Mount += 189 ; STEPS +=5;



}

if (readBuffer =='y')

{

STEP_Mount += 226; STEPS +=6;



}

if (readBuffer =='u')

{

STEP_Mount += 264; STEPS +=7;



}

if (readBuffer =='i')

{

STEP_Mount += 302; STEPS +=8;



}

if (readBuffer =='o')

{

STEP_Mount += 339; STEPS +=9;



}
if (readBuffer =='s')

{
putrsUSARTWill("Step");

WriteUSARTWill(13);

xDes = x + STEP_Mount;

STEP = STEP_Mount;

Step_Flag = 1;

}
if (readBuffer =='b')

{
putrsUSARTWill("Step_back");

WriteUSARTWill(13);

xDes = x - STEP;

STEP = 0;

Step_Flag = 1;

}
// if (readBuffer =='1')

// {


//

// putrsUSARTWill("Step");

// WriteUSARTWill(13);

// xDes = x + STEP_10;

// STEP = STEP_10;

// Step_Flag = 1;

// }

// if (readBuffer =='2')



// {

//

// putrsUSARTWill("Step");



// WriteUSARTWill(13);

// xDes = x + STEP_20;

// STEP = STEP_20;

// Step_Flag = 1;

// }

// if (readBuffer =='3')



// {

//

// putrsUSARTWill("Step");



// WriteUSARTWill(13);

// xDes = x + STEP_30;

// ` STEP = STEP_30;

// Step_Flag = 1;

// }

// if (readBuffer =='4')



// {

//

// putrsUSARTWill("Step");



// WriteUSARTWill(13);

// xDes = x + STEP_40;

// STEP = STEP_40;

// Step_Flag = 1;

// }

// if (readBuffer =='5')



// {

//

// putrsUSARTWill("Step");



// WriteUSARTWill(13);

// xDes = x + STEP_50;

// STEP = STEP_50;

// Step_Flag = 1;

// }

// if (readBuffer =='6')



// {

//

// putrsUSARTWill("Step");



// WriteUSARTWill(13);

// xDes = x + STEP_60;

// STEP = STEP_60;

// Step_Flag = 1;

// }

// if (readBuffer =='7')



// {

//

// putrsUSARTWill("Step");



// WriteUSARTWill(13);

// xDes = x + STEP_70;

// STEP = STEP_70;

// Step_Flag = 1;

// }

// if (readBuffer =='8')



// {

//

// putrsUSARTWill("Step");



// WriteUSARTWill(13);

// xDes = x + STEP_80;

// STEP = STEP_80;

// Step_Flag = 1;

// }

// if (readBuffer =='9')



// {

//

// putrsUSARTWill("Step");



// WriteUSARTWill(13);

// xDes = x + STEP_90;

// STEP = STEP_90;

// Step_Flag = 1;

// }
// ************************D TERM************************

// if (readBuffer =='a')

// {

// putrsUSARTWill("D term: ");



// Kd +=500;

// SendRS232NUM(Kd);

// }

// if (readBuffer =='d')



// {

// putrsUSARTWill("D term: ");

// Kd -=500;

// SendRS232NUM(Kd);

// }

// //******************* P TERM ***********************



// if (readBuffer =='q')

// {


// putrsUSARTWill("P term: ");

// Kp +=10;

// SendRS232NUM(Kp);

// }


// if (readBuffer =='e')

// {


// putrsUSARTWill("P term: ");

// Kp -=10;

// SendRS232NUM(Kp);

// }


//

// if (readBuffer =='o')

// {

// putrsUSARTWill("I term: ");



// Kp =0;

// SendRS232NUM(Ki);

// }

// if (readBuffer =='p')



// {

// putrsUSARTWill("I term: ");

// Kp =700;

// SendRS232NUM(Ki);

// }

// //****************** I TERM *************************



// if (readBuffer =='z')

// {


// putrsUSARTWill("I term: ");

// Ki +=3;

// SendRS232NUM(Ki);

// }


// if (readBuffer =='c')

// {


// putrsUSARTWill("I term: ");

// Ki -=3;

// SendRS232NUM(Ki);

// }


}

// if (readBuffer == '6') {

// PORTBbits.RB6 = ~PORTBbits.RB6;

// WriteUSARTWill(13); //carriage return //or WriteUSART(0x0D); //0x41=A //48 = 0

// WriteUSARTWill(54); //send ASCII 54 = '6' to RS-232

// }
WriteUSARTWill(13); //carriage return //or WriteUSART(0x0D); //0x41=A //48 = 0

//SendRS232Int(x);

//WriteUSARTWill(9);

//SendRS232NUM(vel);

//

//WriteUSARTWill(9);



//SendRS232NUM((int)integError_old);

//

//WriteUSARTWill(9);



//SendRS232NUM(error);

//

//WriteUSARTWill(9);



//SendRS232NUM(Torque_Control);

//

//WriteUSARTWill(9);



//SendRS232NUM((unsigned int)simpleAnalog());

//

//WriteUSARTWill(9);



//SendRS232NUM((unsigned int)simpleAnalog1());
WriteUSARTWill(9);

SendRS232NUM((unsigned int)STEPS);


WriteUSARTWill(9);

SendRS232NUM((unsigned int)STEP_Mount);


//// putrsUSART(ready); // put prompt to USART

//

////this works for getting the 16-bit encoder register value



// number = POSCNTH;

//// charNumber = POSCNTL;

// result = POSCNTL + (number << 8); // High byte of 16-bit encoder count

//

// WriteUSARTWill(13); //carriage return //or WriteUSART(0x0D); //0x41=A //48 = 0



// SendRS232Int(result); // decimal "decode" and send encoder value to RS-232

//

//



////read and printout analog voltage

// result = simpleAnalog();

// WriteUSARTWill(9); //tab

// SendRS232Int(result); // decimal "decode" and send encoder value to RS-232

//

// result = result*16; //to turn 10-bit A/D into 14-bit PWM



//

//

//// WRITE OUT TO 14-BIT PWM PIN



// PWM14out(result);

//// PDC1L = (result & 0xFF); //these are used by Torque control

//// PDC1H = ( (result >> 8) & 0x3F ); // bit shift and mask off to most significant bits

//

////try to print out binary form number (THIS WORKS!!!)



//// WriteUSARTWill(9); //tab

//// SendRS232Int(0b11111111); // decimal "decode" and send encoder value to RS-232

//

//

//



//// ultoa(result, str); //convert number "result" to string

//// putrsUSARTWill(str);

//

// Delay10KTCYx (100); // pause for a moment ( ( ) * 10,000 cycles)



// // AT 40MHz, 10,000 cycles = 1ms

//

//// PORTB = 0xFF;



//// Delay10KTCYx (255); /* pause for a moment (255 * 10,000 cycles) */

//

//



//// PORTB = 0x00;

Delay10KTCYx (255); /* pause for a moment (255 * 10,000 cycles) */

} //end main while loop
CloseUSART();
} //end of Main()

//---------------------------------------------------------------------

// putrsUSARTWill()

// Writes a string of characters in program memory to the USART

//---------------------------------------------------------------------

//special version of putrsUSART that doesn't also output the null byte at the end of the string

void putrsUSARTWill(const rom char *data)

{

do



{ // Transmit a byte

while(BusyUSART());

if(*data != 0) putcUSART(*data); //avoid sending null bit at end of string

} while( *data++ ); //&& !0

}

void WriteUSARTWill(char data)



{

// if(TXSTAbits.TX9) // 9-bit mode?

// {

// TXSTAbits.TX9D = 0; // Set the TX9D bit according to the



// if(USART_Status.TX_NINE) // USART Tx 9th bit in status reg

// TXSTAbits.TX9D = 1;

// }

while( BusyUSART() );



TXREG = data; // Write the data byte to the USART

}

void SendRS232NUM(long int data)



{

char index;

unsigned char outputChar;

int divisor[6] = {10000, 1000, 100, 10, 1, 1};


if (data <0)

{

while(BusyUSART());



TXREG = '-';

data = -data;

}

for (index = 0; index < 5; index++)



{

outputChar = data/divisor[index] + ASCII_NUM_OFFSET;


while( BusyUSART() );

TXREG = outputChar; // Write the data byte to the USART

// could have used WriteUSARTWill( outputChar );

data = data%divisor[index];

}

}

void SendRS232Int(unsigned int data)



{

char index;

unsigned char outputChar;

// #define DECIMAL_DIGITS 5

// int tenThousands, thousands, hundreds, tens, tens, ones, remainder, divisor;

// divisor = 10000;

unsigned int divisor[6] = {10000, 1000, 100, 10, 1, 1};

// int divisor[4] = {100, 10, 1, 1};

// if(TXSTAbits.TX9) // 9-bit mode?

// {


// TXSTAbits.TX9D = 0; // Set the TX9D bit according to the

// if(USART_Status.TX_NINE) // USART Tx 9th bit in status reg

// TXSTAbits.TX9D = 1;

// }


for (index = 0; index < 5; index++) {

outputChar = data/divisor[index] + ASCII_NUM_OFFSET;

// if( (outputChar != ASCII_NUM_OFFSET) ) {

while( BusyUSART() );

TXREG = outputChar; // Write the data byte to the USART

// could have used WriteUSARTWill( outputChar );

// }

data = data%divisor[index];



}

} //end of SendRS232int


void SendRS232Char(char data)

{

char index;



unsigned char outputChar;

// #define DECIMAL_DIGITS 3

unsigned char divisor[4] = {100, 10, 1, 1};
// if(TXSTAbits.TX9) // 9-bit mode?

// {


// TXSTAbits.TX9D = 0; // Set the TX9D bit according to the

// if(USART_Status.TX_NINE) // USART Tx 9th bit in status reg

// TXSTAbits.TX9D = 1;

// }


for (index = 0; index < 3; index++) {

outputChar = data/divisor[index] + ASCII_NUM_OFFSET;

// if( (outputChar != ASCII_NUM_OFFSET) ) {

while( BusyUSART() );

TXREG = outputChar; // Write the data byte to the USART

// could have used WriteUSARTWill( outputChar );

// }

data = data%divisor[index];



}

} //end of SendRS232Char

// SIMPLE analog DOES AN ANALOG CONVERSION AND PUTS VALUES IN "BUFFER"

unsigned int simpleAnalog(void)

{

unsigned int result; // 10-bit A/D value



ADCON0 = 0b00000001;

/// SetChanADC(ADC_CH_0); //to change which channel is sampled

// SetChanADC(1);

ConvertADC(); // start conversion

// ADCON0 = 1;

while( BusyADC() ); // LOOKS FOR END OF CONVERSION

result = ReadADC(); // RESULT OF ANALOG CONVERSION
////this works for getting the 16-bit encoder register value

// number = POSCNTH;

//// charNumber = POSCNTL;

// result = POSCNTL + (number << 8); // High byte of 16-bit encoder count

//

// result = (result & 0x03FF); // only 10 LSBs



return(result);

//-----------

}//--------END OF SIMPLE_ANLG ROUTINE ------
unsigned int simpleAnalog1(void)

{

unsigned int result; // 10-bit A/D value



ADCON0 = 0b00000101;

/// SetChanADC(ADC_CH_0); //to change which channel is sampled

// SetChanADC(1);

ConvertADC(); // start conversion

// ADCON0 = 1;

while( BusyADC() ); // LOOKS FOR END OF CONVERSION

result = ReadADC(); // RESULT OF ANALOG CONVERSION

return(result);

//-----------

}//--------END OF SIMPLE_ANLG ROUTINE ------


void PWM14out(unsigned int result)

{

// WRITE OUT TO 14-BIT PWM PIN



PDC1L = (result & 0xFF); // masking off the MSByte

PDC1H = ( (result >> 8) & 0x03);//0x3F ); // bit shift to right (MSByte to the LSByte)

// and mask off to most significant bits

}//--------END OF PWM14out ROUTINE ------

//----------------------------------------------------------------------------

// High priority interrupt vector


#pragma code InterruptVectorHigh = 0x08

void


InterruptVectorHigh (void)

{

_asm



goto InterruptHandlerHigh //jump to interrupt routine

_endasm


}

//----------------------------------------------------------------------------

// High priority interrupt routine

#pragma code

#pragma interrupt InterruptHandlerHigh
void

InterruptHandlerHigh ()

{

PORTB = (Portb_Data|0b00000001);



if (INTCONbits.TMR0IF)

{ //check for TMR0 overflow

INTCONbits.TMR0IF = 0; //clear interrupt flag

Flags.Bit.Timeout = 1; //indicate timeout

//reset timer

TMR0L = TMR0_LOW_BYTE; //INITIALIZE timer 0

TMR0H = TMR0_HIGH_BYTE; //INITIALIZE timer 0

LATBbits.LATB7 = !LATBbits.LATB7; //toggle LED on RB0

PID_Control();

}

PORTB = (Portb_Data&0b11111110);



// Put the controller here:

//PUT OTHER IF STATMENTS AND INTERRUPTS HERE

} //END OF HIGH PRIORITY INTERRUPT ROUTINE

//_asm


// MOVLW D'49'

// MOVWF TXREG

//_endasm

//lessons learned about serial com (Rs-232)

// putrsUSART( "Hello, the answer is 0." ); //for some reason, the putrsUSART command puts a <0> symbol after the string in quotes

// this is because it prints the NULL at the end of the string

// WriteUSART(46); //46=. //THIS WORKS //0x41=A, 0x48=H

// WriteUSART("."); //doesn't work //46=. //0x41=A, 0x48=H

// putcUSART( "." ); //doesn't work

//// TXREG = 13; // add 48 for 0 (numbers), 65 for upper case "A", 97 for lower case "a"

//THIS WORKS

//WriteUSARTWill(13); //carriage return //or WriteUSART(0x0D); //0x41=A

//number = 'a';

// number = number + 2;

// TXREG = number; // add 48 for 0 (numbers), 65 for upper case "A", 97 for lower case "a"

//THIS WORKS

// WriteUSARTWill(13); //carriage return //or WriteUSART(0x0D); //0x41=A //48 = 0

// SendRS232Int(result); // "decode" and send encoder value to RS-232

// SendRS232Char(number); // "decode" and send CHAR to RS-232

// THIS WORKS!!!!!!!!

// try to print out binary form number THIS WORKS!!!!!!!!

// WriteUSARTWill(9); //tab

// SendRS232Int(0b11111111); // decimal "decode" and send encoder value to RS-232

// SYNTAX FOR DELAYS

// Delay10KTCYx (100); // pause for a moment ( ( ) * 10,000 cycles)

// AT 40MHz, 10,000 cycles = 1ms

// Delay1KTCYx (255); /* pause for a moment (255 * 1,000 cycles) */

// Delay100TCYx(255); /* pause for a moment (255 * 100 cycles) */

// Delay10TCYx(255); /* pause for a moment (255 * 10 cycles) */

//static long int x, x_old, error, integError_old, integError, Kp, Ki, Kd; //these should be signed

//static long int vel, vel_old, control; //these should also be signed

//static int xDes;

// // controller code

// add/declare variable names and initialize in "setup" if necessary


int counter = 0;
void PID_Init(void)

{

int number;



number = POSCNTH;

x = POSCNTL + (number << 8);

x_old = x;

xDes = x ;

error = xDes - x;//0;

vel = 0;


vel_old = 0;

integError = 0;

integError_old = 0;

control = 0;

Kp = 500;

Ki = 3;


Kd = -4000;

}

//after initializing encoder to initial position



void PID_Control(void)

{

int number;



//if (Step_Flag ==1)

//{


//

//

// Step_Data[counter] = x;



// counter++;

//

//



// if (counter ==80)

// {


// int i;

// INTCON =0;

// for (i = 0; i<80; i++)

// {


// WriteUSARTWill(13);

// SendRS232Int(Step_Data[i]);

// }

// INTCON = 0x20;



// }

//}


// In servo loop

////this works for getting the 16-bit encoder register value


//number = POSCNTH;

//WriteUSARTWill(13); //carriage return //or WriteUSART(0x0D); //0x41=A //48 = 0

//SendRS232Int(number);

//number = POSCNTL;

//WriteUSARTWill(9); //carriage return //or WriteUSART(0x0D); //0x41=A //48 = 0

//SendRS232Int(number);

number = POSCNTH;

x = POSCNTL + (number << 8); // High byte of 16-bit encoder count

if(xDes >= x)

{

error = xDes - x;



}

else


{

error = x - xDes;

error = -error;

}

//if (error==0)



//{

// integError_old=0;

//}

if (Step_Flag ==1)



{

error = (Step_Count/1000.0)*error;

Step_Count++;
if (Step_Count == 1000)

{

Step_Flag =0;



Step_Count =1;

}

}



//vel = x - x_old;

vel = 0;


if(x>x_old)

{

vel = x - x_old;



}

else if (x < x_old)

{

vel = x_old - x;



vel = -vel;

}

//WriteUSARTWill(13); //carriage return //or WriteUSART(0x0D); //0x41=A //48 = 0



//WriteUSARTWill(9);

//SendRS232Int(x);

//

//WriteUSARTWill(9);



//SendRS232Int(xDes);

//

//WriteUSARTWill(9);



////

//

//SendRS232NUM((int)(vel));


vel = 0.80 * vel_old + .20 * vel;
if (integError_old+error>99999)

{

integError = 99999;



}

else if (integError_old+error<-99999)

{

integError = -99999;



}

else


{

integError = integError_old + error;

}
/*

if (error<3&&error>-3)

{

integError = 0;



}

*/

//



//WriteUSARTWill(9);

//SendRS232NUM(error);

control = Kp * error + Kd * vel + Ki * integError;

//control = 0;


//if(control==0)

//control =10;

//

//WriteUSARTWill(9);



//SendRS232NUM((int)(control));
// scale this to 14 bit value

if (control<0)

{

control = -control;



PORTB = 0b11111011;

Portb_Data = 0b11111011;

}

else


{

Portb_Data = 0b11111111;

PORTB = 0b11111111;

}

//if (control==0)



//{

//control =1;

//}

control = (int)((control/1000000.0)*1023.0);



if (control>600)

{

control = 600;



}

//WriteUSARTWill(9);

//SendRS232NUM(control);
if (Torque_Flag ==1)

{

control = 0;



Portb_Data = 0b11111111;

PORTB = 0b11111111;

}

if (Torque_Flag ==1 && Torque_Step ==1)



{

control = Torque_Control;

Portb_Data = 0b11111111;

PORTB = 0b11111111;

}

PWM14out(control);



//old_control= control;

//PWM_out = control ;//* something; // to get 14-bit value

x_old = x;

vel_old = vel;

integError_old = integError;

}



tải về 1.15 Mb.

Chia sẻ với bạn bè của bạn:
1   ...   7   8   9   10   11   12   13   14   15




Cơ sở dữ liệu được bảo vệ bởi bản quyền ©hocday.com 2024
được sử dụng cho việc quản lý

    Quê hương