点对点程序msp430与si4432通信
#include
#include
#include
#include
uint8_t serial_rx_buf[64] = {0,};
uint8_t serial_tx_buf[64] = {0,};
uint8_t serial_rx_len = 0;
uint8_t serial_tx_len = 0;
uint8_t serial_rx_pos = 0;
uint8_t serial_tx_pos = 0;
void uart0_sendbuf(uint8_t* pbuf,uint8_t len); void flush_tx_buf(void);
void flush_rx_buf(void);
void systm_config(void);
void timer1_config(void);
void timer1_enable(void);
void timer1_disable(void);
void clock_config(void);
void select_xt1(void);
void dco_config(void);
void uart_config(void);
void spi_config(void);
void si4432_config(void);
void si4432_write_reg( uint8_t addr , uint8_t value ); uint8_t si4432_read_reg( uint8_t addr ); uint8_t spi_writebyte(uint8_t value); uint8_t is_frame_receive = 0; // 串口数据到达 uint8_t rf_tx_buf[64] = {0,}; // 发送缓冲区
uint8_t rf_rx_buf[ {0,}64] =; // 接收缓冲区 uint8_t status1 = 0,status2 = 0;
uint8_t enable1 = 0,enable2 = 0;
void main(void)
{
systm_config();
si4432_config();
timer1_config();
_EINT(); // 打开全局中断,勿忘
P1DIR |= BIT7; // LED输出
printf("Hello MSP430!\r\n");
while(1) //大循环
{
uint8_t rf_rx_len = 0;
uint8_t rf_tx_len = 0;
if( (P8IN & BIT1) == 0x00 ) // 接收
{
si4432_write_reg(0x07, 0x01); //终止接收
status1 = si4432_read_reg(0x03);
status2 = si4432_read_reg(0x04); //清除中断
enable1 = si4432_read_reg(0x05);
enable2 = si4432_read_reg(0x06);
if((status1 & 0x01) == 0x01) /*CRC Error interrupt occured*/
{
printf("crc error\r\n");
si4432_write_reg(0x08,0x02);
si4432_write_reg(0x08,0x00);
}
if((status1 & 0x02) == 0x02) /*packet received interrupt occured*/
{
si4432_write_reg(0x07,0x01);
rf_rx_len = si4432_read_reg(0x4B);
for( uint8_t i = 0 ; i < rf_rx_len ; i++)
{
rf_rx_buf[i] = si4432_read_reg(0x7F); //读接收缓冲器里的数据
}
memcpy(serial_tx_buf,rf_rx_buf,rf_rx_len); //拷贝接收缓冲器到
UARTTXBUF中
serial_tx_len = rf_rx_len; //读取长度 if( rf_rx_len != 0)
{
P1OUT ^= BIT7;
uart0_sendbuf(serial_tx_buf,serial_tx_len);
}
}
si4432_write_reg(0x08,0x02);
si4432_write_reg(0x08,0x00);
si4432_write_reg(0x07,0x05); //进入接收状态
flush_tx_buf();
}
if( is_frame_receive ) //发送
{
is_frame_receive = 0;
// 赋值RF缓冲区,赋值RF发送长度
memcpy(rf_tx_buf,serial_rx_buf,serial_rx_len);
rf_tx_len = serial_rx_len;
si4432_write_reg(0x07, 0x01); // 禁止接收
^= BIT7; P1OUT
si4432_write_reg(0x3E, rf_tx_len); // 填充发送数据包长度
for(uint8_t i=0; i< rf_tx_len; i++)
{
si4432_write_reg(0x7F, rf_tx_buf[i]);
}
// 仅使能发送完成中断
// 包接收中断 CRC错误中断 0x04:使能发送中断
si4432_write_reg(0x05, 0x04); //write 0x04 to the Interrupt Enable 1 register
si4432_write_reg(0x06, 0x00); //write 0x00 to the Interrupt Enable 2 register
// 读中断状态寄存器,清除中断标志位,并
使nIRQ引脚回复为高电平,读03和04即清除nIRQ中断
status1 = si4432_read_reg(0x03); //read the Interrupt Status1 register
status2 = si4432_read_reg(0x04); //read the Interrupt Status2 register
// 启动发送
si4432_write_reg(0x07, 0x09); //使能发送write 0x09 to the Operating Function Control 1 register
//01:禁止接收(保持准备状态);05:使能接收;09:使能发送
// 等待发送完成
while(P8IN & BIT1); //等待P8.1置位nIRQ
status1 = si4432_read_reg(0x03); //read the Interrupt Status1 register
status2 = si4432_read_reg(0x04); //read the Interrupt Status2 register
// 使能接收中断和CRC校验错误中断
si4432_write_reg(0x05, 0x03); //write 0x03 to the Interrupt Enable 1 register
si4432_write_reg(0x06, 0x00); //write 0x00 to the Interrupt Enable 2 register
// 读中断状态寄存器,清楚中断标志为,并使nIRQ引脚回复为高电平 status1 = si4432_read_reg(0x03); //read the Interrupt Status1 register
status2 = si4432_read_reg(0x04); //read the Interrupt Status2 register
// uart0_sendbuf(serial_rx_buf,serial_rx_len);
flush_rx_buf(); // 清除串口接收缓冲区
si4432_write_reg(0x07, 0x05); //write 0x05 to the Operating Function Control 1 register
//01:禁止接收(保持准备状态);05:使能
接收;09:使能发送
}
}
}
void systm_config(void)
{
clock_config(); // 初始化时钟
uart_config(); // 初始化uart 115200-8-N-1
spi_config();
}
void clock_config(void)
{
WDTCTL = WDTPW + WDTHOLD; // 停止看门狗
select_xt1(); // 选择XT1
dco_config(); // ACLK = XT1 = 32.768K // MCLK = SMCLK = 8000K }
void select_xt1(void)
{
// 启动XT1
P7SEL |= 0x03; // P7.0 P7.1 外设功能
UCSCTL6 &= ~(XT1OFF); // XT1打开 UCSCTL6 |= XCAP_3; // 内部电容
do
{
UCSCTL7 &= ~XT1LFOFFG; // 清楚XT1错误标记 }while (UCSCTL7&XT1LFOFFG); // 检测XT1错误标记 }
void dco_config(void)
{
__bis_SR_register(SCG0); // 禁止FLL功能
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_5; // DCO最大频率为16MHz
UCSCTL4 = SELM_4 + SELA_0 +SELS_4;
UCSCTL2 = FLLD_1 + 243; // 设置DCO频率为8MHz
// MCLK = SMCLK= Fdcoclkdiv = (N+1)X(Ffllrefclk/n)
// N为唯一需要计算的值
// Ffllrefclk FLL参考时钟,默认为XT1 // n取默认值,此时为1
// (243 + 1) * 32768 = 8MHz
__bic_SR_register(SCG0); // 使能FLL功能
// 必要延时
__delay_cycles(250000);
// 清楚错误标志位
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
// 清除所有振荡器错误标志位 SFRIFG1 &= ~OFIFG; // 清除振荡器错误
}while (SFRIFG1&OFIFG); // 等待清楚完成
}
void uart_config(void)
{
// 选择P3.4和P3.5的复用功能 P3SEL = BIT4 + BIT5;
UCA0CTL1 = UCSWRST; // 软件复位
UCA0CTL1 |= UCSSEL_2; // 选择SMCLK时钟
UCA0BR0 = 69; // 查表获得
UCA0BR1 = 0; // UCA0BRX和UCA0MCTL数值
UCA0MCTL |= UCBRS_4 + UCBRF_0; //
UCA0CTL1 &= ~UCSWRST; //
UCA0IE |= UCRXIE; // 使能接收中断 }
int putchar(int ch)
{
UCA0TXBUF = ch;
while(!(UCA0IFG & UCTXIFG));
return ch;
}
void uart0_sendbuf(uint8_t *pbuf,uint8_t len)
{
for( uint8_t i = 0 ; i < len ; i++ )
{
putchar(*pbuf++);
}
}
void flush_tx_buf(void)
{
serial_tx_pos = 0;
serial_tx_len = 0;
}
void flush_rx_buf(void)
{
serial_rx_pos = 0;
serial_rx_len = 0;
}
void timer1_config(void)
{
// TA1CCTL0 = CCIE; // CCR0中断使能
TA1CCR0 = 12000; // 匹配值,8MHz约2ms
TA1CTL = TASSEL_2 + TACLR; // MCLK 匹配模式 清零
}
void timer1_enable(void)
{
TA1R = 0;
TA1CTL |= MC0;
TA1CCTL0 = CCIE; // CCR0中断使能
}
void timer1_disable(void)
{
TA1R = 0;
TA1CTL &= ~MC0;
TA1CCTL0 &= ~CCIE; // CCR0中断禁止
}
void spi_config(void)
{
P3SEL |= (BIT1 + BIT2 + BIT3); // P3.1 P3.2 P3.3为输出状态P3.3.2,3.0作
为SPI 引脚使用
UCB0CTL1 |= UCSWRST;
/* SCLK常态低电平,上升沿采样,MSB在前,8位数据,主模式,3-pin,同步模式. */
UCB0CTL0 = UCCKPH + UCMSB + UCMST + UCMODE_0 + UCSYNC; UCB0CTL1 |= UCSSEL_2; /// SMCLK
UCB0BR0 = 2;
UCB0BR1 = 0; /// SCLK频率是SMCLK / 2
UCB0IE &= ~(UCRXIE + UCTXIE); /// 禁止SPI中断
UCB0CTL1 &= ~UCSWRST; // 从复位模式下运行 }
uint8_t spi_writebyte(uint8_t value)
{
while (!(UCB0IFG&UCTXIFG)); // 等待上一次发送完成
UCB0TXBUF = value;
while (!(UCB0IFG&UCRXIFG)); // 等待本次接收完成
return UCB0RXBUF;
}
void si4432_config(void)
{
P3DIR |= BIT0; // CS端口为输出状态 P8DIR &= ~BIT1; // nIRQ端口 输入状态
P3OUT |= BIT0; // CS端口为高电平
uint8_t status1,status2;
// 读中断状态寄存器,清除中断标志为,并使nIRQ引脚回复为高电平 status1 = si4432_read_reg(0x03);
status2 = si4432_read_reg(0x04);
// 软件复位操作
si4432_write_reg(0x07, 0x80);
// 等待POR中断
while ( P8IN & BIT1);
// 读中断状态寄存器,清除中断标志为,并使nIRQ引脚回复为高电平
status1 = si4432_read_reg(0x03);
status2 = si4432_read_reg(0x04);
printf("POR Inter -> 03H [%2XH] 04H [%2XH]\r\n",status1,status2);
// 等待芯片准备完成中断
while ( P8IN & BIT1);
// 读中断状态寄存器,清楚中断标志为,并使nIRQ引脚回复为高电平
status1 = si4432_read_reg(0x03);
status2 = si4432_read_reg(0x04);
printf("CHIP Ready-> 03H [%2XH] 04H [%2XH]\r\n",status1,status2);
// 设置中心频率 472M(避免干扰) 表格生成
si4432_write_reg(0x75, 0x57);
si4432_write_reg(0x76, 0x32); si4432_write_reg(0x77, 0x00);
// 设置发送速率
si4432_write_reg(0x6E, 0x19);
si4432_write_reg(0x6F, 0x9A);
si4432_write_reg(0x70, 0x0C);
// 设置功率 最大
si4432_write_reg(0x6D, 0x1F);
// 设置频率频率偏移 表格生成 47.6K AGC
si4432_write_reg(0x72, 0x4C);
si4432_write_reg(0x71, 0x23); // GFSK FIFO
si4432_write_reg(0x1C, 0x9A);
si4432_write_reg(0x20, 0x3C);
si4432_write_reg(0x21, 0x02);
si4432_write_reg(0x22, 0x22);
si4432_write_reg(0x23, 0x22); si4432_write_reg(0x24, 0x07);
0xFF); si4432_write_reg(0x25,
si4432_write_reg(0x1D, 0x44);
si4432_write_reg(0x1E, 0x0A);
si4432_write_reg(0x2A, 0x48); si4432_write_reg(0x1F, 0x03);
si4432_write_reg(0x69, 0x60);
// 设置包结构和调制方式
// 设置先导码长度为 5字节
si4432_write_reg(0x34, 0x0A);
// 先导码侦测长度为 20bit
si4432_write_reg(0x35, 0x2A);
// 帧首部长度为0 同步字为2字节
si4432_write_reg(0x33, 0x02);
// 设置同步字
si4432_write_reg(0x36, 0x2D); si4432_write_reg(0x37, 0xD4);
// 使能TX RX自动组包功能,使能CRC CRC校验方式为 IBM si4432_write_reg(0x30, 0x8D);
// 禁止帧首部匹配
si4432_write_reg(0x32, 0x00 );
// GPIO 端口设置
si4432_write_reg(0x0C, 0x12);
si4432_write_reg(0x0D, 0x15);
// 设置内部电容
si4432_write_reg(0x09, 0xD7);
// 使能接收状态
si4432_write_reg(0x07, 0x05);
// 使能两种中断
si4432_write_reg(0x05, 0x03); // 包接收中断 CRC错误中断
si4432_write_reg(0x06, 0x00);
// 读中断状态寄存器,清楚中断标志为,并使nIRQ引脚回复为高电平
status1 = si4432_read_reg(0x03);
status2 = si4432_read_reg(0x04);
}
uint8_t si4432_read_reg( uint8_t addr )
{
uint8_t ret_value = 0x00;
P3OUT &= ~BIT0;
spi_writebyte( addr & 0x7f); // 发送寄存器地址 ret_value = spi_writebyte(0xff); // 读取寄存器
内容
财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容
P3OUT |= BIT0;
return ret_value;
}
void si4432_write_reg( uint8_t addr , uint8_t value ) {
P3OUT &= ~BIT0; //引脚拉低
spi_writebyte( (addr & 0x7f) | 0x80 ); // 发送寄存器地址
spi_writebyte(value); // 发送寄存器内容 P3OUT |= BIT0; //拉高
}
#pragma vector = USCI_A0_VECTOR //uart中断
__interrupt void uart_a0_isr(void) {
switch(UCA0IV)
{
case 0:
reak; b
case 2: /* RX */ //接收中断
// 填充发送缓冲区
serial_rx_buf[serial_rx_pos++] = UCA0RXBUF;
serial_rx_len++;
timer1_enable();
break;
case 4: /* TX */
break;
default:
break;
}
}
#pragma vector=TIMER1_A0_VECTOR //定时器中断
void TIMER1_A0_ISR(void) __interrupt
{
// 数据到达
is_frame_receive = 1;
timer1_disable();
}