This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/MSP430G2231:USI-I2C 和 SSD1306

Guru**** 2587365 points
Other Parts Discussed in Thread: MSP430G2231, MSP430G2553

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/612333/ccs-msp430g2231-usi-i2c-and-ssd1306

器件型号:MSP430G2231
主题中讨论的其他器件: MSP430G2553

工具/软件:Code Composer Studio

我想使用 I2C (USI)将 SSD1306与 MSP430G2231搭配使用。

这是我的 MSP430G2553工作代码:

#include 

/*
0xAE、//显示关闭
0x81、//设置对比度控制寄存器
0x7F、//对比度 Wert 127 ok

0x20、//设置存储器地址模式
0x01、//垂直地址模式

0x21、//设置列地址
0x00、//开始地址0
0x7F、//结束地址127

0x22、//设置页面地址
0x00 //开始地址0
0x07,//结束地址7

0x40,//设置开始行地址0

0xA0,//列地址映射到 SEG0

0xA8,//设置比率
0x3F,//最大

值0xC0,//将 COM 输出扫描方向设置为正常模式

0xD3,//设置显示偏移
0x00,// 0

0x8D,多路复用 //设置电荷泵设置
0x14,//在

0xDA 上,//设置 COM 引脚硬件配置
0x12,//替代+禁用重映射

0xD5,//设置显示时钟分频+频率
0x80,//除以1和中等频率

0xD9,//设置预充电预发布器
0x22,//中等(复位值)

0xDB, //设置 vcomh
0x20,// 0.77 x Vcc

0xA4,//输出跟随 RAM 内容

0xAF //显示 on*/


const unsigned char Init[]={0xAE,0x81,0x20,0x01,0x21,0x00,0x7,0x20




,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20




void printC (const unsigned char*数组、unsigned int length){

UCB0CTL1 = UCSWRST;
UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC;// I2C 主模式
UCB0CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK、保持 SW 复位
UCB0BR0 = 0x40; //< 100kHz
UCB0I2CSA = 0x3C; //地址
UCB0CTL1 &=~UCSWRST;
IE2 |= UCB0TXIE;//启用 TX 就绪中断
__DISABLE_INTERRUPT ();
UCB0CTL1 |= UCTR + UCTXSTT;// I2C TX,启动条件


__bis_register (LPM3_bits + GIE);UCB0+






= UCB0bis_t = UCB0+= UCB0bis += UCTXCC_t;// UPM3+= UCB0+= UCB0BIS_R+寄存器= UCB0+= UCB0+= UCB0+= UCB0BIS_BIT_BIT_CLB = UCB0+
_bis_SR_register (LPM3_bits + GIE);
}

UCB0CTL1 |= UCTXSTP;
IE2 &=~UCB0TXIE;

}

void prints (void){
UCB0CTL1 = UCSWRST;
UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC;// I2C 主模式
UCB0CTL1 = UCSBREL_2 + UCSWRST
;使用0x40 SW /复位 //< 100kHz
UCB0I2CSA = 0x3C; //地址
UCB0CTL1 &=~UCSWRST;
IE2 |= UCB0TXIE;//启用 TX 就绪中断
__DISABLE_INTERRUPT ();
UCB0CTL1 |= UCTR + UCTXSTT;// I2C TX,开始条件

__bis_register (LPM3_bits + GIE);UCB0CTL




+ UCTL void + UCTL = UCTL void + UCTL (void);// I2C TX void + UCB0CCTRI + UCTL = UCTL = UCTL = UCTL = UCTL + UCTL void + UCTL = UCTL = UCTL void + UCTL void + UCTL = UCTL = UCTL = UCT








WDTCTL = WDTPW + WDTHOLD;

DCOCTL = CALDCO_8MHZ;//DCO 设置= 8MHz
BCSCTL1 = CALBC1_8MHZ;//DCO 设置= 8MHz

//为 I2C 配置引脚
P1SEL |= BIT6 + BIT7; //引脚初始化
P1SEL2 |= BIT6 + BIT7; //引脚初始化


printC (Init、31);

_delay_cycles (8000000);

printC (Mod、1);

/*
prints();



UCB0TXBUF = 0x00;
_bis_SR_register (LPM3_bits + GIE);


unsigned int i;
对于(i = 500;i > 0;i--){
printD (0xFF);
printD (0x00);
}
Printe();*/

while (1);

}


// USCI_B0数据 ISR
#pragma vector = USCIAB0TX_vector
__interrupt void USCIAB0TX_ISR (void){
IFG2 &&=~UCB0TXIFG;
__BIC_SR_REGISTER_ON_EXIT (LPM3_BITS); //唤醒主代码
}

这是我的 MSP430g2231代码。 大多数基于 MSP430G2x21/G2x31演示- I2C 主发送器/接收器、多字节。

#include 

/const unsigned char Init[]={0xAE、0x81、0x07、0x20、0x01、0x21、0x00、0x7F、0x22、0x00、0x40、0xA0、0x3F、0xC0、0xD3、0x00、0x14、0x14、0x20、0x80、
0x80、0x20、0x80、0x80、0x80、0x80、0x80、0x20、0x80、0x20、0x20、0x80、0x20、0x80、0x80、0x20、0x80、0x20、0x80、0x20、0x20、0x20、0x80、0x20、0x80、0x20、0x80、0x20、0x20、0x80、0x20、0x80、0x20、0x80、0x80、0x20、0x20、0x80、0x20、0x80、0x20、0x20、0x80、0x20、0x80、0x20、0x20、0x80、0x80、0x20、0x20、0x20、0x20、0x80、0x20、0x80、0x20、0x20、0x20、0x80


//有多少字节?

unsigned int number_for_bytes;
unsigned int bla;

void Master_transmit (void);
void Master_receve (void);

void Setup_USI_Master_TX (void);
void Setup_USI_Master_RX (void);

char MST_Data[];//= 0x55; //传输数据的变量
//char SLV_Addr = 0x78;
int I2C_State、Bytecount、transmit = 0; //状态变量
void Data_TX (void);
void Data_RX (void);
int main (void)
{
volatile unsigned int i; //使用易失性来防止删除

WDTCTL = WDTPW + WDTHOLD; //如果
(CALBC1_1MHz=0xFF)则停止看门狗//如果校准常数被擦除
{
while (1); //不加载,陷阱 CPU!!
}
DCOCTL = 0; //选择最低 DCOx 和 MODx 设置
BCSCTL1 = CALBC1_1MHZ; //设置 DCO
DCOCTL = CALDCO_1MHz;

P1OUT = 0xC0; // P1.6 & P1.7上拉、其它到0
P1REN |= 0xC0; // P1.6 & P1.7上拉
P1DIR = 0xFF; //未使用的引脚作为输出
P2OUT = 0;
P2DIR = 0xFF;



while (1)
{
number_for_bytes = 62;
bla = 0;
MASTER_Transmit ();
__no_operation(); //用于 IAR
_DELAY_CYCLES (2000000);

NUMBER_O_FLOG_BENS = 2;
Bla = 1;
MASTER_Transmit ();
__no_operation(); //用于 IAR

__DELAY_CYCLES (800000);
}
}/********


// USI 中断服务例程
//数据传输:状态0 -> 2 -> 4 -> 10 -> 12 -> 14
//数据接收:状态0 -> 2 -> 4 -> 6 -> 8 -> 14
/
#if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_)
#pragma vector = USI_vector
__interrupt void USI_TXRX (void)
#Elif defined (__GNU__)
void __attribute__((interrupt (USI_vector))) USI_TXRX (void

编译器#error!
#endif
{
switch (__even_in_range (I2C_State、14)))
{
情况0://生成起始条件并将地址发送到从器件
P1OUT |= 0x01; // LED 打开:序列启动
Bytecount = 0;
USISRL = 0x00; //生成启动条件...
USICTL0 |= USIGE+USIOE;
USICTL0 &=~USIGE;
如果(发送= 1){
USISRL = 0x78; //地址为0x48 << 1位+ 0 (RW)
}
如果(发送=0){
USISRL = 0x79; // 0x91地址为0x48 << 1位
//+ 1用于读取
}
USICNT =(USICNT & 0xE0)+ 0x08;//位计数器= 8、TX 地址
I2C_STATE = 2; //下一个状态:RCV 地址(N)Ack
中断;

情况2://接收地址确认/应答位
USICTL0 &=~USIOE; // SDA =输入
USICNT |= 0x01; //位计数器=1、接收(N) Ack 位
I2C_STATE = 4; //转到下一状态:检查(N)Ack
中断;

案例4://处理地址 Ack/Nack & handle data TX

if (transmit = 1){
USICTL0 |= USIOE; // SDA =输出
IF (USISRL & 0x01) //如果收到 NACK ...
{//发送停止...
USISRL = 0x00;
USICNT |= 0x01; //位计数器=1、SCL 高电平、SDA 低电平
I2C_STATE = 14; //转到下一状态:生成停止
P1OUT |= 0x01; //打开 LED:错误
}
其他
{//接收到 Ack、TX 数据到从器件...
if (bla){USISRL = Init[ Bytecount];}
否则{USISRL = Mod[Bytecount];}
//USISRL = MST_Data[Bytecount]; //加载数据字节
USICNT |= 0x08; //位计数器= 8、启动 TX
I2C_STATE = 10; //下一状态:接收数据(N)Ack
Bytecount++;
P1OUT &=~0x01; //关闭 LED
中断;
}
}if (transmit =0){

IF (USISRL & 0x01) //如果收到 NACK
{//准备停止条件
USICTL0 |= USIOE;
USISRL = 0x00;
USICNT |= 0x01; //位计数器= 1、SCL 高电平、SDA 低电平
I2C_STATE = 8; //转到下一状态:生成停止
P1OUT |= 0x01; //打开 LED:错误
}
else{Data_RX();} // Ack received


}
中断;

情况6://发送数据确认/ NACK 位
USICTL0 |= USIOE; // SDA =输出
if (Bytecount <= number_for_bytes-2)
{ //如果这不是最后一个字节
USISRL = 0x00; //发送确认
P1OUT &=~0x01; // LED 关闭
I2C_STATE = 4; //再次进入下一状态:data/rcv
Bytecount++;
}

else //最后一个字节:发送 NACK
{
USISRL = 0xFF; //发送 NACK
P1OUT |= 0x01; // LED 打开:通信结束
I2C_STATE = 8; //停止条件
}
USICNT |= 0x01; //位计数器= 1、发送(N) Ack 位
中断;

案例8://准备停止条件
USICTL0 |= USIOE; // SDA =输出
USISRL = 0x00;
USICNT |= 0x01; //位计数器= 1、SCL 高电平、SDA 低电平
I2C_STATE = 14; //转到下一状态:生成停止
中断;

情况10://接收数据确认/应答位
USICTL0 &=~USIOE; // SDA =输入
USICNT |= 0x01; //位计数器= 1、接收(N) Ack 位
I2C_STATE = 12; //转到下一状态:检查(N)Ack
中断;

案例12://处理数据采集/应答和发送停止
USICTL0 |= USIOE;
if (Bytecount = number_for_bytes){// if last byte
USISRL = 0x00;
I2C_STATE = 14; //转到下一状态:生成停止
P1OUT |= 0x01;
USICNT |= 0x01;
} //将 count 设置为1以触发下一状态
否则{
P1OUT &=~0x01; //关闭 LED
DATA_TX(); // TX 字节
}
中断;

情况14://生成停止条件
USISRL = 0x0FF; // USISRL = 1来释放 SDA
USICTL0 |= USIGE; //启用透明锁存器
USICTL0 &=~(USIGE+USIOE);//锁存/SDA 输出被禁用
I2C_STATE = 0; //为下一个 xmt 重置状态机
LPM0_EXIT; //退出活动状态以进行下一个传输
中断;
}

USICTL1 &=~USIIFG; //清除暂挂标志
}


void Data_TX (void){
if (bla){USISRL = Init[ Bytecount];}
否则{USISRL = Mod[Bytecount];}
//USISRL = MST_Data++; //加载数据字节
USICNT |= 0x08; //位计数器= 8、启动 TX
I2C_STATE = 10; //下一状态:接收数据(N)Ack
Bytecount++;
}

void Data_RX (void){
USICTL0 &=~USIOE; // SDA =输入-->冗余
USICNT |= 0x08; //位计数器= 8、RX 数据
I2C_STATE = 6; //下一状态:测试数据和(N)Ack
P1OUT &=~0x01; // LED 关闭
}


void Setup_USI_Master_TX (void)
{
__disable_interrupt ();
Bytecount = 0;
Transmit = 1;
USICTL0 = USIPE6+USIPE7+USIMST+USISWRST;//端口和 USI 模式设置
USICTL1 = USII2C+USIIE; //启用 I2C 模式和 USI 中断
USICKCTL = USIDIV_7+USISSEL_2+USICKPL;// USI clk:SCL = SMCLK/128
USICNT |= USIIFGCC; //禁用自动清除控制
USICTL0 &=~USISWRST; //启用 USI
USICTL1 &=~USIIFG; //清除挂起标志
__ENABLE_INTERRUPT ();
}


void Setup_USI_Master_RX (void)
{
__disable_interrupt ();
Bytecount = 0;
Transmit = 0;
USICTL0 = USIPE6+USIPE7+USIMST+USISWRST;//端口和 USI 模式设置
USICTL1 = USII2C+USIIE; //启用 I2C 模式和 USI 中断
USICKCTL = USIDIV_7+USISSEL_2+USICKPL;// USI CLKS:SCL = SMCLK/128
USICNT |= USIIFGCC; //禁用自动清除控制
USICTL0 &=~USISWRST; //启用 USI
USICTL1 &=~USIIFG; //清除挂起标志
__ENABLE_INTERRUPT();

}

void Master_transmit (void){
Setup_USI_Master_TX();
USICTL1 |= USIIFG; //设置标志并开始通信
LPM0; // CPU 关闭,等待 USI 中断
_delay_cycles (10000); //通信周期之间的延迟
}
void Master_receve (void){
Setup_USI_Master_RX ();
USICTL1 |= USIIFG; //设置标志并开始通信
LPM0; // CPU 关闭、等待 USI 中断
__DELAY_CYCLES (10000); //通信周期之间的延迟
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Lacto、
    那么、您在寻找什么呢? 我该怎么做才能获得帮助?

    此致、
    现金 Hao
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    第二个代码不起作用、我不知道原因。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Lacto、
    有许多原因会导致代码无法正常工作。 我的建议是先检查硬件连接。 然后检查 MSP430G2231的输出数据、如 I2C 端口。 它是否正常工作? 您还可以检查 SDD1306的时序。

    此致、
    现金 Hao
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Latco、
    您是否确定了问题? 或者您需要有关此方面的更多帮助吗?

    此致、
    现金 Hao
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我可以使用 以下工具解决我的问题:github.com/.../msp430_usi_i2c