|
|
PIC間の通信についてどうか教えて下さい。送信側のPICから受信側のPICにi2Cでデータを送信しようとしています。問題は受信側のアドレスをデータとして読み込んでいるということですそこでプログラムの方でackのチェックをしました。
i2c_start();
i2c_write(0x20);
i2c_write(data);
i2c_stop();
とCCSでは関数があるのですが、i2c_write(0x20);のackがかえってきていないということがわかりました。原因がわかるかた、また調べる方法よろしければ教えていただけないでしょうか?
PICは16F877Aを用いています。
送信側プログラム
#include <16f877A.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#device ADC=10
#use delay(clock = 20000000)
#use i2c(MASTER,SDA=PIN_C4,SCL=PIN_C3)
#use rs232(BAUD = 9600, XMIT = PIN_C6, RCV = PIN_C7)
#use fast_io(b)
#use fast_io(d)
#include <stdlib.h>
//A/Dパラメータ
void a_d_converter();
int adcount=0;
int adf=10;
long ad_x=0;
int admax=10;//a/d変換周期(/0.1ms)
int32 data[8]={0};//データの格納
long ad[10];
long ave[8];
long angle=0;
void receive();
long data1;
char idata[10];
int rotaryflag=0;
short ack=0;
short ack2=0;
void main(void)
{
output_float(PIN_C3); //I2C pin float
output_float(PIN_C4);
setup_PSP(PSP_DISABLED);
set_tris_e(0);
//タイマ1の初期設定
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
set_timer1(15536);//約10msecで割り込み
//アナログ変換設定
setup_ADC(ADC_CLOCK_DIV_32);
setup_adc_ports(ALL_ANALOG);
set_tris_b(0x00);
set_tris_d(0x00);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
///メインループ
while(1)
{
if(KBHIT()){
receive();
}
}
}
#INT_TIMER1
void isr1()
{
set_timer1(15536);
a_d_converter();
data[1]=0;
i2c_start(); //スタートコンディション
ack=i2c_write(0x20); //アドレスaddに送信
if(ack==1){
i2c_stop(); //ストップコンディション
printf("ERROR[1]\r\n");
}
if(ack==0){
ack2=i2c_write(rotaryflag);
if(ack2==1){
i2c_stop();
//ストップコンディション
printf("ERROR[2]\r\n");
}
i2c_stop();
}
if(angle >= data1){
rotaryflag=1;
}
if(angle < data1){
rotaryflag=0;
}
}
//A/D変換関数
void a_d_converter(){
adcount++;
set_adc_channel(1);
delay_us(40);
ad[1]=read_adc();
data[1] = data[1] + ad[1];
if(adcount>=adf){
ave[1]=data[1]/adcount;
adcount=0;
if(ave[1] < 345){
angle=(ave[1]+679)*45/128;
}
if(ave[1] >= 345){
angle=(ave[1]-345)*45/128;
}
}
}
void receive(){
gets(idata);
data1 = atol(idata);
}
ここで結果としてprintfでERROR[1]とでるのでi2c_write()のackがかえってきていないようです。
受信側
#include <16f877A.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#device ADC=10
#use delay(clock = 20000000)
#use i2c(SLAVE,SDA=PIN_C4,SCL=PIN_C3,ADDRESS=0x20)
#use rs232(BAUD = 9600, XMIT = PIN_C6, RCV = PIN_C7)
#use fast_io(b)
int dutyd;//走行用モータduty比(/0.1ms)
int dmax;//走行用モータPWM周期
int dr_x=0;
int rotaryflag=1;
int rotaryflag1=1;
void main(void)
{
output_float(PIN_C3); //I2C pin float
output_float(PIN_C4);
set_tris_b(0x00);
//初期パラメータ設定
dutyd=1;//走行用モータduty比(/0.1ms)
dmax=10;//走行用モータPWM周期
setup_PSP(PSP_DISABLED);
set_tris_e(0);
//タイマ1の初期設定
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
set_timer1(63036);//約0.5msecで割り込み
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
output_low(PIN_B4);//enable_dr
output_low(PIN_B1);//enable_dm
output_low(PIN_B5);//in_dr
output_low(PIN_B3);//brake_dr
output_high(PIN_B2);//chop_dr
output_low(PIN_B0);//chop_dm
output_high(PIN_B3);//brake_dr
delay_ms(100);
output_low(PIN_B2);//chop_dr
output_high(PIN_B0);//chop_dm
output_high(PIN_B4);//enable_dr
output_low(PIN_B4);//enable_dr
output_low(PIN_B3);//brake_dr
output_high(PIN_B2);//chop_dr
output_low(PIN_B0);//chop_dm
while(1)///メインループ
{
if(i2c_poll()) {
rotaryflag=i2c_read();
printf("flag1=%d\tdutyd=%d\r\n",rotaryflag,dutyd);
}
}
}
#INT_TIMER1
void isr1()
{
set_timer1(63036);
dr_x++;
if(dr_x==dmax){
dr_x=0;
output_high(PIN_B2);//chop_dr
output_low(PIN_B0);//chop_dm
}
if(dr_x>=dutyd){
output_low(PIN_B2);//chop_dr
output_high(PIN_B0);//chop_dm
}
if(rotaryflag==0){
dutyd=0;
}
if(rotaryflag==1){
dutyd=1;
}
}
受信側PICのprintfの結果;rotaryflagには受信側のアドレスがはいってしまいます。(32)通信できていればrotaryflagに1か0がはいるはずなのですが。。。
PICもまだ勉強不足でよくわからなく、どうか教えていただければ幸いです
|
|