本帖最后由 ddllxxrr 于 2023-8-29 18:48 编辑
杰发的IIC给我一个小震动,也是对我IIC知识的弥补,我一直以为IIC是没有时间要求的(当然太长不行)。
所以我以前一直是管脚驱动,而且在SCLK拉低期间,我想拉多长就拉多和,这时再变SDAT。反正我就是这么就的。也是这么认为的。
但杰发的例程居然要计算速率。
下边是模块原理图:
可以看到有收和发两个硬件组成。
打开例程第一个,I2Cmasterpolling那个,管脚都定义好了,只要把OLED驱动部分加入就行了。尔这部分网上到处都是。
以下是初始化部分,根本不用改:
- oid I2C0_Init(void)
- {
- I2C_ConfigType i2cConfig;
- /*ÇåÁã½á¹¹Ìå±äÁ¿.*/
- memset(&i2cConfig, 0x00, sizeof(i2cConfig));
- /*³õʼ»¯Òý½Å¹¦ÄÜΪI2C.*/
- GPIO_SetFunc(I2C0_SCL_PORT, I2C0_SCL_PIN, GPIO_FUN3);
- GPIO_SetFunc(I2C0_SDA_PORT, I2C0_SDA_PIN, GPIO_FUN3);
- /*ÎÞÂÛÊÇÖ÷»ú»¹ÊÇ´Ó»úģʽ¶¼ÐèÒªÅäÖõIJÎÊý.*/
- i2cConfig.mode = I2C_MASTER; /*ÉèÖÃÖ÷»úģʽ.*/
- i2cConfig.extAddrEn = DISABLE; /*10bitÀ©Õ¹µØÖ·½ûÄÜ.*/
- i2cConfig.interruptEn = DISABLE; /*I2CÖжÏ,BND/SAMF/ARBLOST.*/
- i2cConfig.nackInterruptEn = DISABLE; /*NACKÖжÏ.*/
- i2cConfig.ssInterruptEn = DISABLE; /*×ÜÏßstart»òstopÖжÏ.*/
- i2cConfig.i2cEn = ENABLE; /*ʹÄÜÄ£¿é.*/
- i2cConfig.callBack = NULL; /*Öжϻص÷º¯Êý.*/
- /*Ö÷»úģʽÐèÒªÅäÖõIJÎÊý,ÅäÖóɴӻúģʽ¿ÉºöÂÔ.*/
- /*²¨ÌØÂÊÉèÖÃ
- f = APBʱÖÓ/((sampleCnt+1)*(stepCnt+1)*2)
- µ±APBʱÖÓΪ24M£¬ËùÐè²¨ÌØÂÊΪ100Kbps
- ¿ÉÅäÖðëÂö³å¿í¶ÈstepCntΪ7£¬Ã¿¸ö²ÉÑùµã¿í¶ÈsampleCntΪ9
- Ôò²¨ÌØÂÊ = 16M/((9+1)*(7+1)*2) = 100K
- */
- i2cConfig.masterConfig.sampleCnt = 7; /*ÉèÖò¨ÌØÂÊΪ100Kbps,bandrate=(16M/(10*8*2))=100Kbps.*/
- i2cConfig.masterConfig.stepCnt = 9;
- i2cConfig.masterConfig.ARBEn = ENABLE; /*ÉèÖÃÖ÷»úÖٲù¦ÄÜ.*/
- i2cConfig.masterConfig.SYNCEn = ENABLE; /*ÉèÖÃÖ÷»úSCLͬ²½¹¦ÄÜ.*/
- I2C_Init(I2C0, &i2cConfig);
- }
运得结果在这里放吧,不知怎么了,本来我早晨发贴子,图片就是上不去,也不知道是哪边的事
主函数部分:
- int main(void)
- {
- InitDelay();
- InitDebug();
- printf("I2C0 Polling Master Test\r\n");
- I2C0_Init();
- OLED_Init();
- OLED_Clear();
- OLED_ShowString(16,1, (const uint8_t*)"Hello AC!!!!",16,0);
- OLED_Refresh_Gram();
- OLED_Fill(0,0,128,64,1);
- OLED_ShowString(16,1, (const uint8_t*)"Hello AC!!!!",16,0);
- OLED_Refresh_Gram();
- while (1)
- {
- // mdelay(1000);
- // I2C0_SendData();
- }
- }
|