完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我写PIC18F46J50 I2C有困难。我希望有人能对这件事有所启发。2011 PIC18F46J50数据表通知我们,当使用PIC18F46J50作为主机通过I2C传输字节时,我们通过写入SSPXBUF开始每个字节传输。这设置缓冲满标志(BF)并开始移出字节。在移出第八位之后,清除缓冲器全标志(BF)。然后,发送额外的时钟以允许从属者相应地响应ACK或NACK。在第九时钟之后,SSPXIF位被设置,主时钟被挂起,直到下一个数据字节被加载到SSPXBUF中。我解释这意味着使用SPSSIF来确定字节已经被发送和ACK或NACK收到。在我的小例子中,我正在发送一个控制。(写入)字节,后面是一个地址字节,后面是一个SIR数据字节。在试图使事物工作时,我使用轮询方法,因此用WHELLY()语句执行块,该语句等待FrsSPXIF在发送下一个字节之前被设置。然而,我的逻辑分析器显示只有第一个字节和第三个字节被传输。我已经确定第二个字节会丢失或被践踏,这是为什么?我们不能相信SPXIF与设备数据表相反吗?Windows 7(64位)MPLABX 4.01XC81.41感谢。这里是我的小例子。
以上来自于百度翻译 以下为原文 I am having trouble writing PIC18F46J50 I2C. I hope someone can shed some light on the matter? The 2011 PIC18F46J50 datasheet informs us that when using PIC18F46J50 as master to transmit a byte via I2C, we begin each byte transmission by writing to SSPxBUF. This sets the buffer full flag (BF) and begins shifting out the byte. After the eighth bit has been shifted out the buffer full flag (BF) is cleared. An extra clock is then transmitted to allow the slave to respond with ACK or NACK accordingly. After the ninth clock the SSPxIF bit is set and the master clock is suspended until the next data byte is loaded into SSPxBUF. I interpret this to mean that use SSPxIF being set to determine that the byte has been transmitted and ACK or NACK received. In my trivial example I am transmitting a control (write) byte, followed by a single address byte, followed by a sing data byte. In trying to get things working I am using a polling method and so block execution with a while() statement which waits for SSPxIF to be set before transmitting the next byte. However, my logic analyser shows that only the first and third bytes are being transmitted. I have established that the second byte is getting lost or trampled. Why is this? Can we not trust SSPxIF contrary to the device datasheet? Windows 7 (64-bit) MPLABX 4.01 XC8 1.41 Thanks. Here is my trivial example. /******************************************************************** * Project: TestI2C * Module: main.c * Created: 28Oct17 * Compiler: XC8 1.41 ******************************************************************** * This USB device is powered by internal source - not USB bus. * */ /** CONFIGURATION Bits **********************************************/ #pragma config WDTEN = OFF //WDT disabled (enabled by SWDTEN bit) //#pragma config PLLDIV = 3 //Divide by 3 (12 MHz oscillator input) #pragma config PLLDIV = 2 //JGB Divide by 2 (internal 8MHz input) #pragma config STVREN = ON //stack overflow/underflow reset enabled #pragma config XINST = OFF //Extended instruction set disabled #pragma config CPUDIV = OSC1 //No CPU system clock divide #pragma config CP0 = OFF //Program memory is not code-protected //#pragma config OSC = HSPLL //HS oscillator, PLL enabled, HSPLL used by USB #pragma config OSC = INTOSCPLL //JGB Internal OSC with PLL #pragma config FCMEN = OFF //Fail-Safe Clock Monitor disabled #pragma config IESO = OFF //Two-Speed Start-up disabled #pragma config WDTPS = 32768 //1:32768 #pragma config DSWDTOSC = INTOSCREF //DSWDT uses INTOSC/INTRC as clock #pragma config DSBOREN = OFF //Zero-Power BOR disabled in Deep Sleep #pragma config DSWDTEN = OFF //Disabled #pragma config DSWDTPS = 8192 //1:8,192 (8.5 seconds) #pragma config IOL1WAY = OFF //IOLOCK bit can be set and cleared #pragma config MSSP7B_EN = MSK7 //7 Bit address masking #pragma config WPFP = PAGE_1 //Write Protect Program Flash Page 0 #pragma config WPEND = PAGE_0 //Start protection at page 0 #pragma config WPCFG = OFF //Write/Erase last page protect Disabled #pragma config WPDIS = OFF //WPFP[5:0], WPEND, and WPCFG bits ignored #pragma config T1DIG = ON //Sec Osc clock source may be selected #pragma config LPT1OSC = OFF //high power Timer1 mode #include #define I2CDEV_RTCC_R 0xDF #define I2CDEV_RTCC_W 0xDE #define I2CDEV_SCL_TRIS TRISBbits.TRISB4 #define I2CDEV_SDA_TRIS TRISBbits.TRISB5 #define I2CDEV_SEND_ACK SSP1CON2bits.ACKDT=0, SSP1CON2bits.ACKEN=1;while(SSP1CON2bits.ACKEN) #define I2CDEV_SEND_NACK SSP1CON2bits.ACKDT=1, SSP1CON2bits.ACKEN=1;while(SSP1CON2bits.ACKEN) #define I2CDEV_SEND_RESTART SSP1CON2bits.RSEN=1;while(SSP1CON2bits.RSEN) #define I2CDEV_SEND_START SSP1CON2bits.SEN=1;while(SSP1CON2bits.SEN) #define I2CDEV_SEND_STOP SSP1CON2bits.PEN=1;while(SSP1CON2bits.PEN) /******************************************************************** * MAIN *******************************************************************/ int main(void) { TRISBbits.TRISB3 = 0; //Set output for SMD LED LATBbits.LATB3 = 0; //Enable the PLL and wait 2+ms until the PLL locks before enabling USB module { unsigned int pll_startup_counter = 600; OSCTUNEbits.PLLEN = 1; while(pll_startup_counter--); } //Setup I2C I2CDEV_SCL_TRIS = 1; I2CDEV_SDA_TRIS = 1; SSP1ADD = 0x77; //I2C = 100kHz @ 48MHz Fosc SSP1STAT = 0x00; //Power-on default SSP1STATbits.SMP = 0; //Slew = OFF for 100Hz SSP1CON1 = 0x00; //Power-on default SSP1CON1bits.SSPEN = 1; //Enable I2C and config pins SSP1CON1bits.SSPM3 = 1; //I2C Master mode, Clock = FOSC/(4 * (SSPxADD + 1)) SSP1CON1bits.SSPM2 = 0; SSP1CON1bits.SSPM1 = 0; SSP1CON1bits.SSPM0 = 0; SSP1CON2 = 0x00; //Power-on default /**************************************************************** * MAIN LOOP ***************************************************************/ while(1) { //Create approx. 1 second delay for(unsigned int i = 0; i < 1024; i++) { for(unsigned int i = 0; i < 1024; i++); } //Flash confidence LED LATBbits.LATB3 = ~LATBbits.LATB3; //Send I2C write sequence I2CDEV_SEND_START; SSP1BUF = I2CDEV_RTCC_W; while(!PIR1bits.SSP1IF); PIR1bits.SSP1IF = 0; SSP1BUF = 0x00; while(!PIR1bits.SSP1IF); PIR1bits.SSP1IF = 0; SSP1BUF = 0x80; while(!PIR1bits.SSP1IF); PIR1bits.SSP1IF = 0; I2CDEV_SEND_STOP; } } /* end */ |
|
相关推荐
7个回答
|
|
消除所有这些软件延迟。不能保证他们会做任何事情。使用编译器延迟。宏在关联的标志上等待清除,然后代码在SSPIF上等待。你不必等待两者。
以上来自于百度翻译 以下为原文 Get rid of all of those software delays. There is no guarantee that they will do anything at all. Use the compiler delays. Your macros wait on the associated flag to clear, then your code waits on SSPIF. You don't need to wait for both. |
|
|
|
另外,在你的例子中的主要问题是发送启动条件设置SSPIF,但是在发送第一个数据字节之前你没有清除它,所以你将直接通过第一个等待循环。
以上来自于百度翻译 以下为原文 Agree with the above. additionally, the major problem in your example is that sending the start condition sets SSPIF, but you don't clear it before sending the first data byte, so you will fall straight through the first wait loop. |
|
|
|
谢谢你,但是你提到的软件延迟是什么?在初始化部分(PLLY SARTUPTPO计数器)中出现的延迟是从PIC18F46J50全速USB板的微芯片演示项目中获取的代码。主回路中的延迟(INTI)与所报告的问题无关,但这是我能够创建的最简单的方法。在保持我的代码完全透明的情况下,大约1秒的延迟。在我的实际应用中,我使用定时器产生的中断,但认为这会增加代码的不必要的复杂性。再次,宏是从微芯片USB库中获取的,但是我不能看到宏和我的代码之间的任何重复检查。
以上来自于百度翻译 以下为原文 Thank you jtemples, but which software delays are you referring to? The delay presented in the initialisation section (pll_startup_counter) is code taken from Microchip demonstration project for the PIC18F46J50 Full Speed USB Board. The delay presented in the main loop (int i) has nothing to do with the reported issue, but is the most simple way in which I can create an approximate 1-second delay whilst maintaining full transparency of my code. In my actual application I use timer generated interrupts, but thought that would add unnecessary complexity to the code. Again, the macros are taken from the Microchip USB library, but I cannot see any duplication of checking between the macros and my code. |
|
|
|
这些,我想:使用α-DelayyMS(1000)或类似的。根据上面的PLL计数器,它确实来自MLA和…我不确定它是否有任何需要,也不确定它是否在工作。但这不应该是个问题。
以上来自于百度翻译 以下为原文 These, I suppose: //Create approx. 1 second delay for(unsigned int i = 0; i < 1024; i++) { for(unsigned int i = 0; i < 1024; i++); } Use __delay_ms(1000) or alike. As per the PLL counter above, it's from the MLA indeed and... I am not sure it has any need nor if it's working. But that one should not be an issue. |
|
|
|
谢谢QHB。在编写ToSSP1BUF之前,我将测试代码更改为CurrsSp1,这导致了三字节的传输。结果,我回到微芯片PIC18F46J50数据表上,看看我错过了什么。我找不到任何关于通过发送I2C启动、停止或重新启动信号引起的对SSPXIF的更改。谢谢。
以上来自于百度翻译 以下为原文 Thank you qhb. I changed the test code to clear SSP1IF before writing to SSP1BUF and this resulted in transmission of three bytes as intended. As a result, I went back to the Microchip PIC18F46J50 datasheet to see what I missed. I could not find any mention of changes to SSPxIF caused by sending I2C Start, Stop or Restart signals. Thank you. |
|
|
|
第311页。图19-21:第一个起始位定时“在开始位完成后,硬件清除SEN位并设置SSPXIF位”第314页。图19-23:I2C占用主模式波形(传输,7位或10位地址)“见SSPXIF转到高在开始条件结束。
以上来自于百度翻译 以下为原文 Page 311. "FIGURE 19-21: FIRST START BIT TIMING" "At completion of Start bit, hardware clears SEN bit and sets SSPxIF bit" Page 314. "FIGURE 19-23: I2C™ MASTER MODE WAVEFORM (TRANSMISSION, 7-BIT OR 10-BIT ADDRESS)" see SSPxIF go high at the end of the START condition. |
|
|
|
哈!我完全错过了。其他图表,如第316页的图19-25,清楚地显示了SSPXIF的动作。它只是显示微芯片文档需要非常仔细的阅读。-谢谢。
以上来自于百度翻译 以下为原文 Ha! I completely missed that. Other diagrams, such as Figure 19-25 on page 316, clearly show the action on SSPxIF. It just goes to show that Microchip documentation requires very careful reading. :-) Thank you. |
|
|
|
只有小组成员才能发言,加入小组>>
5238 浏览 9 评论
2028 浏览 8 评论
1950 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3204 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2253 浏览 5 评论
774浏览 1评论
664浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
592浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
674浏览 0评论
574浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 20:31 , Processed in 1.537131 second(s), Total 89, Slave 72 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号