1.ADC
扫描模式只能一下4个扫描,DMA重复模式必须把dma中的响应中断关掉才会一直跑,不然自己再打开吧。开了中断,那对不起采样一次响应中断一次。感觉我自己管理比这个dma好用,反正你也全部响应。更正,
更正,是响应第一次中断之后才会采样一次响应一次,响应中断之后再次打开就可以了,不过还是很麻烦
void DMA_Start(dma_vector_t vect_num, uint8_t ctrl_data_num, dma_mode_t mode,
dma_size_t size, uint16_t count, void *src_adr, void *dst_adr)
{
volatile uint8_t * sfr_addr;
uint8_t rptsel, damod, samod;
if(((uint32_t)src_adr & 0xF0000000) == 0x40000000)
{
samod = 0; /* source address is mapped to peripherial area*/
}
else
{
samod = 1; /* source address is not mapped to peripherial area*/
}
if(((uint32_t)dst_adr & 0xF0000000) == 0x40000000)
{
damod = 0; /* destination address is mapped to peripherial area*/
}
else
{
damod = 1; /* destination address is not mapped to peripherial area*/
}
if(!samod & damod)
{
rptsel = 0; /* destination is the repeat area */
}
else if(samod & !damod)
{
rptsel = 1; /* source is the repeat area */
}
else
{
rptsel = 0; /* ToDo: change the value according to your needs for repeate mode */
}
// log_d("samod:%d,damod:%d,rptsel=%d",samod,damod,rptsel);
DMAVEC->VEC[vect_num] = ctrl_data_num;
DMAVEC->CTRL[ctrl_data_num].DMACR = (size << CTRL_DMACR_SZ_Pos) | (0 << CTRL_DMACR_RPTINT_Pos) |(0 << CTRL_DMACR_CHNE_Pos) |
(damod << CTRL_DMACR_DAMOD_Pos) | (samod << CTRL_DMACR_SAMOD_Pos) |
(rptsel << CTRL_DMACR_RPTSEL_Pos)| (mode << CTRL_DMACR_MODE_Pos);
DMAVEC->CTRL[ctrl_data_num].DMBLS = 1;
DMAVEC->CTRL[ctrl_data_num].DMACT = count;
DMAVEC->CTRL[ctrl_data_num].DMRLD = count;
DMAVEC->CTRL[ctrl_data_num].DMSAR = (uint32_t)src_adr;
DMAVEC->CTRL[ctrl_data_num].DMDAR = (uint32_t)dst_adr;
/* init DMA registers */
CGC->PER1 |= CGC_PER1_DMAEN_Msk; //时钟
DMA->DMABAR = DMAVEC_BASE;
sfr_addr = &DMA->DMAEN0;
*(sfr_addr + vect_num / 8) |= 1 << (vect_num % 8); /* DMAENn = 1 */
}
我本来想用通过设置 选择模式、硬件触发等待模式、连续采样,然后在adc中断里改变通道,等指定的通道采样完毕然后设置为adc待机,等待下一次硬件触发,结果你在中断里面设置adc待机,那对不起,硬件等待模式再也不触发adc中断了。解决方式,关了之后再打开,就可以了
ADC->ADM0 &= ~ADCS; //关闭
ADC->ADM0 |= ADCS;
经测试,这样设置会导致多响应一次中断,改进后是这样的
ADC_Stop();
ADC_Start(ADC->ADS);//这个通道设置为你的起始通道
2.串口0
串口0当波特率设置115200会设置不成功,因为那个计算波特率的函数计算误差差不多是0.64%(64MHZ)的差异,里面限制了0.2%的误差就不进行初始化了。
MD_STATUS UART_BaudRateCal(uint32_t fclk_freq, uint32_t baud, uart_baud_t *pvalue)
{
MD_STATUS status = MD_ERROR;
int32_t baud_err;
uint32_t baud_cal;
uint32_t fmck_freq;
unsigned char i, j;
for (i = 0; i < 16; i++)
{
fmck_freq = fclk_freq / sps_tbl[i];
for (j = 2; j < 128; j++)
{
baud_cal = fmck_freq / (j + 1) / 2;
baud_err = 10000 * baud_cal / baud - 10000; /* n ten thousandths */
if (abs(baud_err) < 20) /* 0.2% */ //如果设置115200,这里限制改大一点,差不多是64左右,可以设置为100.也就是1%
{
pvalue->prs = i;
pvalue->sdr = j;
printf("fclk_freq = %10dHz, baud = %6dbps, prs = %2d, sdr = %3d, errors = %3d\n", fclk_freq, baud, pvalue->prs, pvalue->sdr, baud_err);
status = MD_OK;
return (status);
}
}
}
return (status);
}
3.DMA
属实是把我看呆了,还得改SCT文件,这个DMA类似于核显吃内存一样,原文(732页):
通过
DMABAR
寄存器将分配
DMA
的控制数据和向量表的
704
字节区域设置到
RAM
区。
DMABAR
寄存器的设置值为
“20000000H”
时的存储器映像例子如图
21-2
所示。
DMA
控制数据区的
640
字节中
DMA
不使用的空间能用作
RAM
。
厉害厉害,这么小的片子都给你用上了等同于核显的技术,还不赶快感谢中微哥。
向量表是固定的,控制的数据区是不固定的,注意大小,越往后占用的内存越大,所以尽量靠前。
还有这个如果是adc中断里面改了通道,dma接收的还是最早初始化的通道,有点奇怪。
所以说别乱用库文件,感觉是赶工的,一点技术支持没有,还得自己踩坑。。。
总的来说,依托答辩,不如stm32的一根,甚至还没辉芒微好用。