![]() |
|
Tài trợ cho PIC Vietnam |
Giao tiếp USB, CAN, I2C, SPI, USART... Những giao tiếp được tích hợp trên PIC |
|
Ðiều Chỉnh | Xếp Bài |
![]() |
#11 |
Nhập môn đệ tử
Tham gia ngày: Apr 2008
Bài gửi: 1
: |
I2C đọc từ slave về master
Các bác giúp gửi giá trị của thang ghi POSCNTH, POSCNTL từ slave lên master với
Code Master: #include <18f4431.h> #include <stdlib.h> #include <math.h> #include <def_4431.c> #FUSES NOWDT, HS, NOPUT, NOPROTECT #use delay(clock=20000000) #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8) #use I2C(MASTER,SDA=PIN_D2,SCL=PIN_D3) #define slave 0x10 /////////////////////////////////////////////////////////////// ///////////////////////Khai bao bien PID////////////////////// int16 read; int8 v=0,high,low; int16 PWM; int16 feedback_value = 0,real_v; ///////////////////////////////////////////////////////////// /////////////////////////Nhan du lieu tu may tinh//////////// #INT_RDA void getvalue() { int i; char s[3]; for(i=0;i<3;i++) s[i]=getc(); v=atol(s); } //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// int16 read_I2C_2byte(int8 slave_address) { int16 value_read; i2c_start(); i2c_write(slave_address+1); high=i2c_read(1); delay_us(10); low=i2c_read(0); i2c_stop(); value_read=make16(high,low); value_read=value_read/5.2; printf(" %Ld\n\r",value_read); return value_read; } //////////////////////Setup QEI///////////////////////////////// void setup_QEI() { QEICON = QEI_4XPER | VELOCITY_DIV_4; QEICON = 0b11011011; MAXCNT = 800; POSCNT = 0; POSCNTH = 0; // High byte of 16-bit encoder count POSCNTL = 0; // low byte CAP1CON = 0b010011000; DFLTCON = 0b01110010; setup_timer_5 (T5_INTERNAL | T5_DIV_BY_4); } ////////////////////////////////////////////////////////// //////////////////Read Encoder/////////////////////////// #INT_TIMER1 void read_encoder() { set_timer1(32875); read = POSCNT; POSCNT=0; real_v = read/5.2; read=0; } ///////////////////////////////////////////////////////// ////////////////////PID Control///////////////////////// void pidcontrol() { unsigned char kp = 2; unsigned char ki = 0.000003; unsigned char kd = 0.005; int16 set_value = 0; int16 delta_t=0.0065; signed long error_value = 0; static signed long pre_error = 0; static signed long integral = 0; signed long derivative = 0; feedback_value = real_v; set_value = v; error_value = set_value -feedback_value; integral = integral + error_value; derivative = (error_value - pre_error)/delta_t; PWM = PWM+ (kp * error_value) + (ki * integral) + (kd * derivative); if (PWM > 1020) { PWM = 1020; } else if (PWM < -1020) {PWM = -1020;} pre_error = error_value; } /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// void main() { int16 value_read; delay_ms(500); setup_QEI(); enable_interrupts(INT_RDA); enable_interrupts(INT_TIMER1); enable_interrupts(GLOBAL); setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); setup_timer_2(T2_DIV_BY_1,255,1); setup_ccp2(CCP_PWM); set_pwm2_duty(0); set_timer1(32875); while(true) { pidcontrol(); set_pwm2_duty(PWM); value_read=read_I2C_2byte(slave); } } Code Slave #include <18f4431.h> #include <stdlib.h> #include <math.h> #include <def_4431.c> #FUSES NOWDT, HS, NOPUT, NOPROTECT #use delay(clock=20000000) #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8) #use I2C(SLAVE,SDA=PIN_D2,SCL=PIN_D3,address=0x10,fast= 500000,force_hw) /////////////////////////////////////////////////////////////// ///////////////////////Khai bao bien PID////////////////////// int8 value_read; int16 read; int16 PWM; int16 feedback_value = 0,real_v; /////////////////////////////////////////////////////////// //////////////////////Setup QEI///////////////////////////////// void setup_QEI() { QEICON = QEI_4XPER | VELOCITY_DIV_4; QEICON = 0b11011011; MAXCNT = 800; POSCNT = 0; POSCNTH = 0; // High byte of 16-bit encoder count POSCNTL = 0; // low byte CAP1CON = 0b010011000; DFLTCON = 0b01110010; setup_timer_5 (T5_INTERNAL | T5_DIV_BY_4); } ////////////////////////////////////////////////////////// //////////////////Read Encoder/////////////////////////// #INT_TIMER1 void read_encoder() { set_timer1(32875); read = POSCNT; POSCNT=0; real_v = read/5.2; read=0; } ///////////////////////////////////////////////////////// ////////////////////Send to Master///////////////////////// #INT_SSP void i2c_isr() { int8 state; state = i2c_isr_state(); if(state<0x80) value_read = i2c_read(); if(state>=0x80) { if (state==0x80) i2c_write(POSCNTH); if (state==0x81) i2c_write(POSCNTL); } } //////////////////////////////////////////////////////////////// ////////////////////PID Control///////////////////////// void pidcontrol() { unsigned char kp = 2; unsigned char ki = 0.000003; unsigned char kd = 0.005; int16 set_value = 0; int16 delta_t=0.0065; signed long error_value = 0; static signed long pre_error = 0; static signed long integral = 0; signed long derivative = 0; feedback_value = real_v; set_value = 20; error_value = set_value -feedback_value; integral = integral + error_value; derivative = (error_value - pre_error)/delta_t; PWM = PWM+ (kp * error_value) + (ki * integral) + (kd * derivative); if (PWM > 1020) { PWM = 1020; } else if (PWM < -1020) {PWM = -1020;} pre_error = error_value; } /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// void main() { setup_QEI(); enable_interrupts(INT_TIMER1); enable_interrupts(GLOBAL); enable_interrupts(INT_SSP); setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); setup_timer_2(T2_DIV_BY_1,255,1); setup_ccp2(CCP_PWM); set_pwm2_duty(0); set_timer1(32875); while(true) { pidcontrol(); set_pwm2_duty(PWM); delay_ms(100); } } |
![]() |
![]() |
Ðiều Chỉnh | |
Xếp Bài | |
|
|