1.ADC
- 采样保持?
F28335芯片内部含有ADC外设,实现模拟量->数字量的转换。
ADC的转换包括采样保持量化和编码;采样就是将时间上的连续量转化为时间的离散量,将采样的结果保存直到下次采样叫保持——采样保持电路。
- DSP自带ADC外设
F28335的ADC是12位,具有16个通道(2组),但只有一个转换器,两个采样保持器(S/H)。16位的结果寄存器返回ADC转换的结果,转换后的数字量:
其中ADC采集模块的输入信号的两个端子是:正极:ADCINAx ,负极是:ADCL0
- 何为排序器?
因为只有一个转换器,而有16路的输入,所以需要排序器控制转换的顺序。 - 何为级联/双排序?
变为1个16状态排序器;2个独立的8状态排序器 - 何为顺序/同步(SMODE_SEL)?
顺序(0)相当于串行,一次转换一个;同步(1)相当于并行,一次对应A,B组搞两个。
其实如果没有特殊要求的话直接级联排序器+顺序/同步就够用。
2.SCI(两根线,一个发一个收)
- 串口通信(Serial Communication),是指外设和计算机间通过数据信号线、地线等按位进行传输数据的一种通信方式,属于串行通信方式。SCI/SPI/IIC
- 串口是一种接口标准,它规定了接口的电气标准,没有规定接口插件电缆以及使用的协议。RS232/485
- DSP28335有三个SCI串口,由于dsp是ttl电平(1-2.4V;0-0.4V),需要用MAX232进行电平转换。
- 主要寄存器SCITXBUF,SCIRXBUF,波特率产生
- SCI信号接受
标志位RXENA为1,使能接收器接受数据。
数据达到SCIRXD引脚,检测起始位。
数据从寄存器到接受缓冲器SCIRXBUF,产生中断申请,标志位RXRDY为1,表示已接受一个新字符。
程序读SCIRXBUF,标志位RXRDY清除 - SCI信号发送
TXENA为1,使能发送器。写数据到SCITXBUF寄存器,TXRDY为低
SCITXBUF中的值进入移位寄存器,TXRDY变高。 - 波特率
3.ADC的配置
- 外设高速时钟
ADC时钟:CPS:0,对HSOCLK不分频 - 运行方式:CONT_RUN:1连续运行
- 级联+顺序
排序器模式:SEQ_CASC:1级联
SMODE_SEL=0 默认顺序采样 - 初始化转换的最多通道数MAX_CONV(最大16)
配置转换的次序CHSELxx,决定了最终转换的结果放在寄存器的位置。
顺序采样,通过控制寄存器CONVxx的4位值确定输入引脚,最高位确定采样保持缓冲器,其他三位定义具体输入引脚。
ADCCHSELSEQ1-4包含了CONV00-15;比如说想输入ADCINA0,就在对应次序的CONVxx赋值-0000(第一个0表示A组,000表示0号引脚)
关于结果寄存器:由于是12位的ADC,所以只用了12位,而寄存器16位的,所以说ADCRESULTn的高12位才有效,所以要移位4。
void ADC_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK=1;//开启ADC时钟
EDIS;
EALLOW;
SysCtrlRegs.HISPCP.all=3;//HISPCP分频150M/2*3=25MHz
EDIS;
//初始化adc
InitAdc();//TI的对ADC模块的参考源校准完毕
//我们需要做的,工作方式,采样方式,工作频率,采样通道
AdcRegs.ADCTRL1.bit.ACQ_PS=0x0f;//采样滤波,没设置SMODE_SEL默认顺序采样
AdcRegs.ADCTRL1.bit.SEQ_CASC=1;//级联
AdcRegs.ADCTRL1.bit.CONT_RUN=1;//连续运行
AdcRegs.ADCTRL3.bit.ADCCLKPS=1;//不再分频
AdcRegs.ADCCHSELSEQ1.bit.CONV00=0x0;//ADCINA0
AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0x0;//最大通道数,0-15
AdcRegs.ADCTRL2.all=0x2000;//触发源-软件触发
}
Uint16 Read_ADCValue(void)
{
while(AdcRegs.ADCST.bit.INT_SEQ1==0);
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;
return AdcRegs.ADCRESULT0>>4;//转换的结果右移,本来是放在高12位,注意这里的result0
}
主函数中读取这个值:
float adc_vol;
adc_vol=(float)Read_ADCValue()*3.0/4095;
4.SCI的配置+float转str
#include "uart.h"
void UARTa_Init(Uint32 baud)
{
unsigned char scihbaud=0;
unsigned char scilbaud=0;
Uint16 scibaud=0;
scibaud=37500000/(8*baud)-1;
scihbaud=scibaud>>8;
scilbaud=scibaud&0xff;
EALLOW;
SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A
EDIS;
InitSciaGpio();
//Initalize the SCI FIFO
SciaRegs.SCIFFTX.all=0xE040;
SciaRegs.SCIFFRX.all=0x204f;
SciaRegs.SCIFFCT.all=0x0;
// Note: Clocks were turned on to the SCIA peripheral
// in the InitSysCtrl() function
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
SciaRegs.SCICTL2.all =0x0003;
SciaRegs.SCICTL2.bit.TXINTENA =1;
SciaRegs.SCICTL2.bit.RXBKINTENA =1;
SciaRegs.SCIHBAUD =scihbaud; // 9600 baud @LSPCLK = 37.5MHz.
SciaRegs.SCILBAUD =scilbaud;
// SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop back
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void UARTa_SendByte(int a)
{
while (SciaRegs.SCIFFTX.bit.TXFFST != 0);
SciaRegs.SCITXBUF=a;
}
void UARTa_SendString(char * msg)
{
int i=0;
while(msg[i] != '\0')
{
UARTa_SendByte(msg[i]);
i++;
}
}
5.效果
6.关于外设时钟配置PCLKCRx
Dsp28335通过外部时钟信号,OSC和PLL产生倍频时钟信号CLKIN后,CLKIN经过CPU后产生时钟SYSCLKOUT(CLKIN和SYSCLKOUT频率是一样的),SYSCLKOUT给各个片内外设提供时钟信号。
为了实现低功耗和提供高低频率时钟信号,需要把SYSCLKOUT进一步分频。
除了SPI,SCI,McBSP模块使用低频时钟,ADC使用高频时钟外,其他外设模块均采用SYSCLKOUT时钟。
怎么省电?
- 外设时钟控制寄存器PCLKCR——不用的外设就不打开其时钟0
- 高低频外设时钟分频寄存器HISPCP,LOSPCP——设置速率
Char和char*和char[]
- Char *str1=”abcd”;
字符串常量,存储在静态存储区,是只读。是将匿名数组的首地址赋值给对象。相当于str1存放的是匿名数组“abcd”的地址,这时char *str2=str1就意味着str1的地址给str2。
- Char str2[ ]=”abcd”;
字符串数组,是将匿名函数的内容复制到对象所属的空间。可以str2[1]=‘a’;不可以str2++; - Char *str3=&str2就是str3[]=“abcd”;
但是可以char[ ]可以隐式的转换为char*;也就是说函数输入(char * msg),,此时有一个数组的str2[];就是以使用该函数。
或者直接
char msg=“123”;
*和&
*表示指针;&表示取地址
但是如果ptr是指针,*ptr就是就相当于那个变量x