完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我对PIC处理器来说是相当新的,最近在C中转换为编程。我试图找出如何使I2C可用比特敲击,因为它似乎是有问题的使用推荐的工作圈套,这对我来说还没有起作用。我只是想把字符发送到一个带有0x3e(0x7c,如果左移)地址的LCD显示器。我发布的样例代码是我从各种其他例子中创建的,与好奇心PIC MZ EF板一起工作。我使代码非常简单,只做主要功能中的所有操作。因为我有另一个有很多功能的程序,而且很难跟上。有人知道这为什么不起作用吗?我以前的问题,我似乎已经解决了,在那里没有收到从奴隶的确认。所以我已经打开了LED,因为它完成了代码的某些部分。目前我没有任何测试设备的访问,但应该有一些在未来。无论如何,这是我有什么,任何修改或建议?
以上来自于百度翻译 以下为原文 I'm fairly new to PIC processors and recently transitioned to programming in C. I'm trying to figure out how to make I2C useable by bit banging as it seems problematic using the recommended work arounds, which haven't worked for me yet. I'm just trying to send characters to an LCD display with an address of 0x3E (0x7C if left shifted). The sample code i'm posting is just something I created from various other examples edited to work with the Curiosity PIC MZ EF board. I made the code very simple, just do everything in the main function, because I had another program with many functions and it was harder to follow. Does anyone know why this isn't working? I had previous problems, which I seemed to have solved, where it wasn't receiving an acknowledgment from the slave. So I have it turn on the LEDs as it completes certain segments of the code. Currently I don't have access to any test equipment but should have some again in the future. Anyway here's what I have, any corrections or suggestions? // Setup for PIC32MZ EF device 200 MHz operation // Device Config Bits in DEVCFG1: #pragma config POSCMOD = EC #pragma config FNOSC = SPLL #pragma config FSOSCEN = ON #pragma config IESO = ON #pragma config OSCIOFNC = ON #pragma config FPLLICLK = PLL_POSC #pragma config FPLLIDIV = DIV_3 #pragma config FPLLRNG = RANGE_5_10_MHZ #pragma config FPLLMULT = MUL_50 #pragma config FPLLODIV = DIV_2 #pragma config FDMTEN = OFF #pragma config DMTCNT = DMT31 #pragma config FWDTEN = OFF #pragma config ICESEL = ICS_PGx2 //#pragma config UPLLEN = ON #pragma config UPLLFSEL = FREQ_24MHZ #define SYS_FREQ (200000000L) #define PB3FREQ SYS_FREQ/2 // No longer used //********* I2C Bus Timing - uS ************ #define I2CSTARTDELAY 50 #define I2CSTOPDELAY 50 #define I2CDATASETTLE 20 #define I2CCLOCKHIGH 100 #define I2CHALFCLOCK 50 #define I2CCLOCKLOW 100 #define I2CACKWAITMIN 100 #define SHORTDELAY 50 /* LEDs defined */ #define led_1 LATEbits.LATE3 #define led_2 LATEbits.LATE4 #define led_3 LATEbits.LATE6 #define led_4b LATBbits.LATB0 #define led_4g LATBbits.LATB1 #define led_4r LATBbits.LATB5 #define SCL LATAbits.LATA14 // The SCL output pin #define SCL_read PORTAbits.RA14 // The SCL input pin #define SDA_out LATAbits.LATA15 // The SDA output pin #define SDA_in PORTAbits.RA15 // The SDA input pin #define HIGH 1 #define LOW 0 #define SCL_mode TRISAbits.TRISA14 // To set port RA14 as input or output #define SDA_mode TRISAbits.TRISA15 // To set port RA15 as input or output #define EnableOut 0x0000 // To set the ports as outputs /* Define and create a microseconds units timer function here */ //********* Header files ********** #include #include #include #include #include "p32mz2048efm100.h" // Variables Declarations int ack; int Address = (0x3E << 1) & 0xFE; // The value Ox3E is the address of the // LCD display according to the datasheet int Data = 0x54; int Num = 10; int delay; int count; int x; int timeout; int repeat = 10; int Byte = 0x54; int delay_us(); void main() { PB3DIVbits.PBDIV = 1; // Peripheral Bus 3 Clock (PBCLK3) Divisor set to 1:2 PB3DIVbits.ON = 1; // Peripheral Bus 3 Output (PBCLK3) Clock Enable TRISA = EnableOut; // Set all Port A bits as outputs TRISB = EnableOut; // Set all port B bits as outputs TRISE = EnableOut; // Set all port E bits as outputs ODCAbits.ODCA14 = 1; // Enable Open Drain on Port A14 ODCAbits.ODCA15 = 1; // Enable Open Drain on Port A15 // Make sure all LEDs are off led_1 = 0; // LEDs 1,2,3 are active high, low turns off led_2 = 0; led_3 = 0; led_4b = 1; // LED 4b,g,r are active low, high turns off. led_4g = 1; led_4r = 1; /* I2C Start condition, data line goes low when clock is high */ SCL = HIGH; // Make clock high delay_us(SHORTDELAY); SDA_out = LOW; // Transition SDA from low to high to initiate start delay_us(SHORTDELAY); SDA_out = HIGH; delay_us(I2CHALFCLOCK); /* Assign the slave address*/ Byte = Address; int count; for(count=8;count>0;count--) // Send 8 bits (one byte) of data { SCL = LOW; // Make the clock low delay_us(I2CCLOCKLOW); if( (Byte & 0x80)== 0) // Get one individual the Bit of the byte { SDA_out = LOW; // If the place holder of the byte is zero, send a zero bit } else { SDA_out = HIGH; // If the place holder of the byte is one, send a one bit } SCL = HIGH; delay_us(I2CCLOCKHIGH); Byte = Byte << 1; // Shift next bit into position } /* First acknowledge */ timeout = 10; //5000; SCL = HIGH; do { if(SDA_in == 0) { ack = 1; //SCL_mode = 0; SDA_mode = 0; break; } //} delay_us(SHORTDELAY); if (timeout) { timeout--; } } while(timeout); SCL = LOW; delay_us(SHORTDELAY); // End of 1st acknowledge led_1 = 1; // Address sent to slave device, first acknowledgment received /* Send characters to the LCD */ for(x=0; x <10; x++){ Byte = Data; int count; for(count=8;count>0;count--) // Send 8 bits (one byte) of data { SCL = LOW; // Make the clock low delay_us(I2CCLOCKLOW); if( (Byte & 0x80)== 0) // Get one individual the Bit of the byte { SDA_out = LOW; // If the place holder of the byte is zero, send a zero bit } else { SDA_out = HIGH; // If the place holder of the byte is one, send a one bit } SCL = HIGH; delay_us(I2CCLOCKHIGH); Byte = Byte << 1; // Shift next bit into position } /* Acknowledge from slave indicating were characters received */ timeout = 5000; SCL = HIGH; do { if(SDA_in == 0) { ack = 1; //SCL_mode = 0; SDA_mode = 0; break; } delay_us(SHORTDELAY); if (timeout) { timeout--; } } while(timeout); SCL = LOW; delay_us(SHORTDELAY); // End of acknowledge } led_3 = 1; // End of transmissions /* I2C Stop condition, clock goes high when data is low */ SCL = 0; SDA_mode = 0; // Make SDA pin an output delay_us(SHORTDELAY); SDA_out = 0; SCL = 1; delay_us(I2CCLOCKHIGH); SDA_out = 1; delay_us(I2CCLOCKHIGH); } // This creates a delay specified in 1 microsecond (uS) increments int delay_us( int delay){ unsigned long downcount; downcount = delay * ((unsigned long)(.00001 / (1.0 / SYS_FREQ))); while( downcount > 0) { downcount--; } led_2 = 1; // Timer function was called and completed } |
|
相关推荐
2个回答
|
|
不要将SDA和SCL线设置为输出,并将它们设置为高/低。这不是I2C如何工作。设置RelaveLATS低,设置/清除TIS位以模拟开漏(或使用开漏函数)。此外,除非使计数变量易失,否则您的延迟函数可能会被优化,除此之外,我还为PIC32 A张贴了一些I2C位BoG代码。回到这里。
以上来自于百度翻译 以下为原文 Don't set the SDA and SCL lines as outputs and drive them high/low. That is not how I2C works. Set the relavent LATs low and set/clear the TRIS bits to emulate open drain (or use the open drain function). Also, your delay functions are likely to be optimised away unless you make the count variable volatile. Other than that, I posted some I2C bit-bang code for PIC32 a while back here. |
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
5013 浏览 9 评论
1923 浏览 8 评论
1856 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3072 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2148 浏览 5 评论
581浏览 1评论
441浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
478浏览 0评论
378浏览 0评论
IPECMD命令烧录AVR128DA48芯片,报找不到芯片错误
862浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-21 19:59 , Processed in 1.182047 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号