调试6:RL78 AD采样麦克风放大电压信号:
1、放大电路:
2、实物图:
3、相关资料:
电压放大芯片:
LM358.pdf
麦克风:
MSMAS42Z.pdf
4、关键程序:
在调试5的基础上:
ADPC = _04_AD_ADPC_3ANALOG;
/* Set ANI0 - ANI3 pin as analog input */
PM2 |= 0x0FU;
AD输入选择通道3.
采样程序:
void ADC_Calculation_Mic(void)
{
if (samples >= 3)
{
samples = 0;
}
AD_Read(&ADC1_result[samples]); // Store the conversion result in the buffer
g_mic = ADC1_result[samples];
samples++;
}
主程序中的主循环中执行:
AD_SelectADChannel(ADCHANNEL3); // Switch to external voltage (Channel 2)
for (i=0; i < 100; i++)
{
NOP();
}
ADC_Calculation_Mic();
if(g_mic<450)
{
LCD_write_english_string(0,0,"|| ");
}
if(g_mic>450&&g_mic<500)
{
LCD_write_english_string(0,0,"|||||| ");
}
if(g_mic>500&&g_mic<550)
{
LCD_write_english_string(0,0,"|||||||||| ");
}
if(g_mic>550)
{
LCD_write_english_string(0,0,"||||||||||||||");
}
LCD_Accel_Value1(3,1,g_mic);
5、测试视频:(背景音是我用嘴吹麦克风的声音,可以看到数据和图形都在变化!)
调试7:RL78与MSP-EXP430FR5739开发板无线通讯(传递三轴加速度值,超声波距离和温度值)
原来用430做过这个实验,所以算是一种移植吧!
1、功能:把MSP-EXP430FR5739开发板上的三轴加速度值和超声波模块采集的距离值以及热敏电阻的值通过无线模块Nrf24l01传送给RL78然后通过其LCD显示出数据的变化。
LCD的布局:
关于“MSP-EXP430FR5739开发板”相信大家不会陌生了!我这就把他的手册分享一下吧!
MSP-EXP430FR5739 usersguide.pdf
至于Nrf24l01的操作其实比较简单,根据时序编出驱动程序后就可以移植到任何一款单片机上!
NRF24l01.pdf
2、关键程序:
//---------------------NRF24L01引脚定义------------------------
#define CE_ON() P0_bit.no5=HIGH;
#define CE_OFF() P0_bit.no5=LOW;
#define CSN_ON() P0_bit.no6=HIGH;
#define CSN_OFF() P0_bit.no6=LOW;
#define MOSI_ON() P4_bit.no1=HIGH;
#define MOSI_OFF() P4_bit.no1=LOW;
#define SCK_ON() P4_bit.no2=HIGH;
#define SCK_OFF() P4_bit.no2=LOW;
#define MISO_IN P14_bit.no6==HIGH
#define IRQ_IN P14_bit.no7==HIGH
具体驱动:
uchar SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
uchar status,byte_ctr;
CSN_OFF(); //使用SPI
status = SPI_RW(reg); //写地址
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) //写数据
SPI_RW(*pBuf++);
CSN_ON(); // 设置高
return(status); //
}
uchar SPI_RW_Reg(BYTE reg, BYTE value)
{
uchar status;
CSN_OFF(); // CSN low, init SPI transaction
status = SPI_RW(reg); // 选择寄存器
SPI_RW(value); // 写入数据
CSN_ON(); // CSN high again
return(status); // return nRF24L01 status byte
}
uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
uchar status,byte_ctr;
CSN_OFF(); // SPI使能
status = SPI_RW(reg); // 选择寄存器
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
pBuf[byte_ctr] = SPI_RW(0); // 读取寄存器
CSN_ON();
return(status); // return nRF24L01 status byte
}
//-------------------IO口初始化函数-------------------------------
void IO_Init(void)
{
CE_OFF(); // 待机模式
CSN_ON(); // SPI禁止
SCK_OFF(); // SPI时钟信号低
}
//----------------------------SPI单字节写入函数---------------------------
uchar SPI_RW(unsigned char byte)
{
uchar bit_ctr;
SCK_OFF();
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
if(byte & 0x80)
{
MOSI_ON();
}
else
{
MOSI_OFF(); // output 'byte', MSB to MOSI
}
byte = (byte << 1); // shift next bit into MSB..
SCK_ON(); // Set clk high..
if(MISO_IN)
{
byte |= BIT0; // capture current MISO bit
}
else
{
byte &=~BIT0;
}
SCK_OFF(); // set clk low
}
MOSI_OFF(); //PULL DOWN THE MOSI
return(byte); // return read byte
}
BYTE SPI_Read(BYTE reg)
{
BYTE reg_val;
CSN_OFF(); // SPI片选使能
SPI_RW(reg); // 选择寄存器
reg_val = SPI_RW(0); // 读出寄存器的值
CSN_ON(); // CSN高终止SPI通信
return(reg_val); // return register value
}
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
unsigned char revale=0;
//SetRX_Mode();
sta=SPI_Read(STATUS); // 读状态寄存器
if(sta&0x40) // 如果是接收数据中断
{
CE_OFF(); //不是能发送或接收
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);//读数据
revale =1;//表示接收到数据
}
SPI_RW_Reg(WRITE_REG+STATUS,sta);// clear RX_DR or TX_DS or MAX_RT interrupt flag
return revale;
}
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE_OFF(); //不是能发送或接收, 为待机状态
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); //写发送地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //设置P0接收地址,默认为5字节
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); //写Tx有效数据
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 数据通道0自动应答允许
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 接收数据通道0允许
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); //应答500us,最大自动重发10次
SPI_RW_Reg(WRITE_REG + RF_CH, 20); //设置工作通道频率
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // 0dB,2M
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // 使能中断,16位CRC,发射模式,PWR_UP
CE_ON();
Delay(100); //>10us
//sta=SPI_Read(STATUS); // read register STATUS's value
//SPI_RW_Reg(WRITE_REG+STATUS,SPI_Read(READ_REG+STATUS)); // clear interrupt flag(TX_DS)
}
void SetRx_Mode(void)
{
CE_OFF(); //禁止发送或接收
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 数据通道0接收地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 数据通道0自动应答允许
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 接收数据通道0允许
SPI_RW_Reg(WRITE_REG + RF_CH, 20); // 设置工作通道频率
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //数据通道0有效数据宽度
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //0dB,2M
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); //使能所有中断,PWR_UP,接收模式
CE_ON(); //启动发送或接收
Delay(6000);
}
至于具体数据的处理,那都是430里的程序,我这里主要讲的是RL78无线接收的程序:
主程序中:
编辑LCD界面:
lcdUpdateLine(0,"Acc(g): Angle:");
lcdUpdate("X: .","Y: .");
lcdUpdateLine(3,"Z: .");
lcdUpdateLine(4,"a: T(C):");
lcdUpdateLine(5,"s: cm|");
lcdUpdateChar(1, 4, 46);
lcdUpdateChar(2, 4, 46);
lcdUpdateChar(3, 4, 46);
lcdUpdateChar(4, 4, 46);
lcdUpdateChar(0, 7, 124);
lcdUpdateChar(1, 7, 124);
lcdUpdateChar(2, 7, 124);
lcdUpdateChar(3, 7, 124);
lcdUpdateChar(4, 7, 124);
循环中判断无线模块是否工作:
while (1)
{
if(nRF24L01_RxPacket(RxBuf))
{
其中为数据的处理:
Judge(1,2,RxBuf[0]);
Judge(2,2,RxBuf[2]);
Judge(3,2,RxBuf[4]);
LCD_Accel_Value( 1, 3, RxBuf[1]);
LCD_Accel_Value( 2, 3, RxBuf[3]);
LCD_Accel_Value( 3, 3, RxBuf[5]);
LCD_Accel_Value( 4, 3, RxBuf[6]);
LCD_Accel_Value1( 5, 12,RxBuf[7]);
S=RxBuf[9]*256+RxBuf[8];//超声波的数据处理
n1=S/10000;
n2=(S%10000)/1000;
n3=(S%1000)/100;
n4=(S%100)/10;
n5=S%10;
lcdUpdateChar(5, 2,n1+48);
lcdUpdateChar(5, 3,n2+48);
lcdUpdateChar(5, 4,n3+48);
lcdUpdateChar(5, 5,46);
lcdUpdateChar(5, 6,n4+48);
lcdUpdateChar(5, 7,n5+48);
//倾角的计算
//X
if(RxBuf[0]==45)
{
Xg=-((float)RxBuf[1]/100);
}
else if(RxBuf[0]==43)
{
Xg=((float)RxBuf[1]/100);
}
if(Xg<-1)
{
Xg=-1;
}
else if(Xg>1)
{
Xg=1;
}
Xg=100*(180*asin(Xg)/3.14);
if(Xg<0)
{
Xg=fabs(Xg);
lcdUpdateChar(1, 8,45);
LCD_Accel_Value2(1,9,(int)Xg);
}
else
{
lcdUpdateChar(1, 8,43);
LCD_Accel_Value2(1,9,(int)Xg);
}
//Y
if(RxBuf[2]==45)
{
Yg=-((float)RxBuf[3]/100);
}
else if(RxBuf[2]==43)
{
Yg=((float)RxBuf[3]/100);
}
if(Yg<-1)
{
Yg=-1;
}
else if(Yg>1)
{
Yg=1;
}
Yg=100*(180*asin(Yg)/3.14);
if(Yg<0)
{
Yg=fabs(Yg);
lcdUpdateChar(2, 8,45);
LCD_Accel_Value2(2,9,(int)Yg);
}
else
{
lcdUpdateChar(2, 8,43);
LCD_Accel_Value2(2,9,(int)Yg);
}
//Z
if(RxBuf[4]==45)
{
Zg=-((float)RxBuf[5]/100);
}
else if(RxBuf[4]==43)
{
Zg=((float)RxBuf[5]/100);
}
if(Zg<-1)
{
Zg=-1;
}
else if(Zg>1)
{
Zg=1;
}
Zg=100*(180*asin(Zg)/3.14);
if(Zg<0)
{
Zg=fabs(Zg);
lcdUpdateChar(3, 8,45);
LCD_Accel_Value2(3,9, (int)Zg);
}
else
{
lcdUpdateChar(3, 8,43);
LCD_Accel_Value2(3,9,(int)Zg);
}
}
这里是将此模块设置为接收模式:
SPI_RW(FLUSH_RX); //清空接收缓冲
Delay(60000);
SetRx_Mode();
}
3、图片:
4、调试视频(拉动超声波模块,转动开发板XYZ数据变化,按住热敏电阻温度值变化)
调试8:RS232串口通信(通过串口助手实现字符的收发,同时收到的内容显示在LCD上,并且解决了LCD同时显示中英文的问题)
1、利用串口2:
使用了U转串的转接板,将串口接出!这样实现了调试和串口通讯两不误!
2、图片:
图中带白色线的为U转串!
发送和接收的情况.
3、关键程序:
主程序中初始化:
UART2_Init();
SAU1_Init();
UART2_Start();
void UART2_Init(void)
{
ST1 |= _0002_SAU_CH1_STOP_TRG_ON | _0001_SAU_CH0_STOP_TRG_ON; /* disable UART2 receive and transmit */
STMK2 = 1U; /* disable INTST2 interrupt */
STIF2 = 0U; /* clear INTST2 interrupt flag */
SRMK2 = 1U; /* disable INTSR2 interrupt */
SRIF2 = 0U; /* clear INTSR2 interrupt flag */
SREMK2 = 1U; /* disable INTSRE2 interrupt */
SREIF2 = 0U; /* clear INTSRE2 interrupt flag */
/* Set INTST2 low priority */
STPR12 = 1U;
STPR02 = 1U;
/* Set INTSR2 low priority */
SRPR12 = 1U;
SRPR02 = 1U;
/* Set INTSRE2 low priority */
SREPR12 = 1U;
SREPR02 = 1U;
SMR10 = _0020_SAU_SMRMN_INITIALVALUE | _0000_SAU_CLOCK_SELECT_CK00 | _0000_SAU_TRIGGER_SOFTWARE | _0002_SAU_MODE_UART | _0000_SAU_TRANSFER_END;
SCR10 = _8000_SAU_TRANSMISSION | _0000_SAU_INTSRE_MASK | _0000_SAU_PARITY_NONE | _0080_SAU_LSB | _0010_SAU_STOP_1 | _0007_SAU_LENGTH_8;
SDR10 = _CE00_UART2_TRANSMIT_DIVISOR;
NFEN0 |= _10_SAU_RXD2_FILTER_ON;
SIR11 = _0004_SAU_SIRMN_FECTMN | _0002_SAU_SIRMN_PECTMN | _0001_SAU_SIRMN_OVCTMN; /* clear error flag */
SMR11 = _0020_SAU_SMRMN_INITIALVALUE | _0000_SAU_CLOCK_SELECT_CK00 | _0100_SAU_TRIGGER_RXD | _0000_SAU_EDGE_FALL | _0002_SAU_MODE_UART | _0000_SAU_TRANSFER_END;
SCR11 = _4000_SAU_RECEPTION | _0400_SAU_INTSRE_ENABLE | _0000_SAU_PARITY_NONE | _0080_SAU_LSB | _0010_SAU_STOP_1 | _0007_SAU_LENGTH_8;
SDR11 = _CE00_UART2_RECEIVE_DIVISOR;
SO1 |= _0001_SAU_CH0_DATA_OUTPUT_1;
SOL1 |= _0000_SAU_CHANNEL0_NORMAL; /* output level normal */
SOE1 |= _0001_SAU_CH0_OUTPUT_ENABLE; /* enable UART2 output */
/* Set RxD2 pin */
PM1 |= 0x10U;
/* Set TxD2 pin */
P1 |= 0x08U;
PM1 &= 0xF7U;
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function starts the UART2 module operation.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
void UART2_Start(void)
{
STIF2 = 0U; /* clear INTST2 interrupt flag */
STMK2 = 0U; /* enable INTST2 interrupt */
SRIF2 = 0U; /* clear INTSR2 interrupt flag */
SRMK2 = 0U; /* enable INTSR2 interrupt */
SREIF2 = 0U; /* clear INTSRE2 interrupt flag */
SREMK2 = 0U; /* enable INTSRE2 interrupt */
SO1 |= _0001_SAU_CH0_DATA_OUTPUT_1; /* output level normal */
SOE1 |= _0001_SAU_CH0_OUTPUT_ENABLE; /* enable UART2 output */
SS1 |= _0002_SAU_CH1_START_TRG_ON | _0001_SAU_CH0_START_TRG_ON; /* enable UART2 receive and transmit */
}
在中断程序中:
#pragma vector = INTSR2_vect
__interrupt void MD_INTSR2(void)
{
UCHAR rx_data;
rx_data = RXD2;
if (gUart2RxLen > gUart2RxCnt)
{
*gpUart2RxAddress = rx_data;
gpUart2RxAddress++;
gUart2RxCnt++;
if (gUart2RxLen == gUart2RxCnt)
{
UART2_ReceiveEndCallback();
}
}
else
{
UART2_SoftOverRunCallback(rx_data);
}
}
#pragma vector = INTST2_vect
__interrupt void MD_INTST2(void)
{
if (gUart2TxCnt > 0U)
{
TXD2 = *gpUart2TxAddress;
gpUart2TxAddress++;
gUart2TxCnt--;
}
else
{
UART2_SendEndCallback();
}
}
其中:
MD_STATUS UART2_ReceiveData(UCHAR *rxbuf, USHORT rxnum)
{
MD_STATUS status = MD_OK;
if (rxnum < 1U)
{
status = MD_ARGERROR;
}
else
{
gUart2RxCnt = 0U;
gUart2RxLen = rxnum;
gpUart2RxAddress = rxbuf;
}
return (status);
}
MD_STATUS UART2_SendData(UCHAR* txbuf, USHORT txnum)
{
MD_STATUS status = MD_OK;
if (txnum < 1U)
{
status = MD_ARGERROR;
}
else
{
gpUart2TxAddress = txbuf;
gUart2TxCnt = txnum;
STMK2 = 1U; /* disable INTST2 interrupt */
TXD2 = *gpUart2TxAddress;
gpUart2TxAddress++;
gUart2TxCnt--;
STMK2 = 0U; /* enable INTST2 interrupt */
}
return (status);
}
在主程序中执行一次:
UART2_ReceiveData(RxBuf,14);之后
会进入接收中断函数:
接收中断函数执行完后进入:
接收回调函数:
void UART2_ReceiveEndCallback(void)
{
UART2_SendData(RxBuf,14);
//Nokia_Clear_Line(5);
Nokia_Clear_Line(4);
Nokia_Clear_Line(5);
for(int j=0;j<14;j++)
{
if((j%2==0)&&(RxBuf[j]&0x80))
{
c=j*6;//间距12
for(int k=0;k<28;k++)
{
if((RxBuf[j]==Hanzi[k])&&(RxBuf[j+1]==Hanzi[k+1]))
{
NOKIA_5110_write_chinese_string(c,4,12,1,Wezhi[k/2],0);
}
}
j++;
}
else
{
lcdUpdateChar(4,j,RxBuf[j]);
}
}
//lcdUpdateLine(5,RxBuf);
/* Start user code. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */
}
这里执行了串口发送程序和LCD判断中英文并显示的程序,其中:
unsigned char Hanzi[28]={"瑞萨开发板串口测试:我爱你!"};
unsigned char Wezhi[14]={0,1,2,3,4,5,6,7,8,9,10,11,12,13};//瑞萨开发板串口测试:我爱你!
unsigned char c=0;
中文使用的是查询方法得到的。
而在发送中断函数结束后进入回调函数:
void UART2_SendEndCallback(void)
{
for(int i=0;i<16;i++)
{
RxBuf[i]=0;
}
UART2_ReceiveData(RxBuf,14);
/* Start user code. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */
}
清除接受Buffer,同时再次启动接收!!
4、视频:
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 | |
【分享评测,赢取加热台】使用8051单片机驱动WS2812被打赏40分 |