日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]如果簡(jiǎn)單的使用USART的話配置相當(dāng)簡(jiǎn)單,只要配置一下波特率,數(shù)據(jù)長(zhǎng)度,停止位長(zhǎng)度,校驗(yàn)位。然后再設(shè)置一下串口的引腳,輸入為上后輸入,輸出為利用推挽輸出。這樣一來(lái)串口就配置好了,如果使用庫(kù)則一目了然,如果使

如果簡(jiǎn)單的使用USART的話配置相當(dāng)簡(jiǎn)單,只要配置一下波特率,數(shù)據(jù)長(zhǎng)度,停止位長(zhǎng)度,校驗(yàn)位。然后再設(shè)置一下串口的引腳,輸入為上后輸入,輸出為利用推挽輸出。這樣一來(lái)串口就配置好了,如果使用庫(kù)則一目了然,如果使用寄存器操作會(huì)繁瑣一點(diǎn)找各個(gè)寄存器,因?yàn)樵O(shè)置波特率和設(shè)置數(shù)據(jù)長(zhǎng)度等這些并不在一個(gè)寄存器中設(shè)置完成,還有可能忘記個(gè)別設(shè)置而無(wú)法找其原因。但寄存器操作的效率會(huì)很高。如下配置:

void USART_Initial(uint32_t Baud)

{

USART_InitTypeDef USART_InitStruct;

USART_GPIO(); //配置串口引腳

USART_InitStruct.USART_BaudRate=Baud; //波特率

USART_InitStruct.USART_WordLength=USART_WordLength_8b;//數(shù)據(jù)長(zhǎng)度

USART_InitStruct.USART_StopBits=USART_StopBits_1;//停止位

USART_InitStruct.USART_Parity=USART_Parity_No;//奇偶校驗(yàn)

USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流失能

USART_InitStruct.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//使能接收和發(fā)送

USART_Init(USART1,&USART_InitStruct);

USART_Cmd(USART1,ENABLE);//打開(kāi)串口

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//開(kāi)中斷,本代碼只在接收時(shí)用到

}

void USART_GPIO(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;

GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&GPIO_InitStruct);

GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;

GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;

GPIO_Init(GPIOA,&GPIO_InitStruct);

GPIO_SetBits(GPIOA,GPIO_Pin_9|GPIO_Pin_10);

}

我使能的USART1為PA9和PA10兩個(gè)串口線。

如果使能到串口中斷則在NVIC中設(shè)置好中斷向量斷并設(shè)置好優(yōu)先級(jí),并在串口寄存器中使能該中斷。

void NVIC_USART_Initial(void)

{

NVIC_InitTypeDef NVIC_InitStruct;

NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;

NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;

NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStruct);

}

(中斷優(yōu)先級(jí)分組為2)

此時(shí)你可以在串口的中斷服務(wù)代碼中寫(xiě)入你想處理的代碼。至于你想是接收中斷還是發(fā)送中斷或者傳送錯(cuò)誤中斷還是奇偶校驗(yàn),偵錯(cuò)誤等中斷你可以設(shè)置USART_ITConfig中設(shè)置,在void USART_Initial(uint32_t Baud)函數(shù)中最后一句第二個(gè)參數(shù)進(jìn)行設(shè)置。

如果你想使能printf或者scanf來(lái)串口傳輸請(qǐng)看我的另一篇博文。http://blog.sina.com.cn/s/blog_79fbaced01011tpj.html

而串口的其它功能則沒(méi)有用到,至于智能卡個(gè)人覺(jué)得應(yīng)該挺有意思的,以后興許會(huì)搞搞。而串口的同步模式不知道他和SPI比是不是速度更快,它的傳輸則由發(fā)送數(shù)據(jù)時(shí)產(chǎn)生CLK時(shí)鐘和些時(shí)鐘進(jìn)行同步,接收數(shù)據(jù)也只有在此時(shí)才可以接收,也就是不可以獨(dú)立的接收數(shù)據(jù)。

博主也試了串口DMA不中斷是可以傳輸?shù)模钱?dāng)我打開(kāi)DMA傳輸完成中斷時(shí),發(fā)現(xiàn)串口沒(méi)有數(shù)據(jù),以為串口速度根不上DMA就提高了波特率發(fā)現(xiàn)還是不行。但當(dāng)我使能DMA半傳輸中斷時(shí)能夠中斷也能傳輸?shù)侵袛喑绦驘o(wú)法執(zhí)行。。等高手回答。

下面則是ADC。因?yàn)閷?shí)驗(yàn)儀上的ADC引腳引出來(lái)有限,所以很多功能未實(shí)現(xiàn),首先就是ADCON這個(gè)東西一直有點(diǎn)混。一直以為使能此位這前校驗(yàn)ADC(手冊(cè)上說(shuō)校驗(yàn)ADC是ADCON=0必須在兩個(gè)周期以上,但手冊(cè)上又說(shuō)ADCON=0時(shí)ADC消耗基本為0)后試過(guò)只有打開(kāi)此位才可以校驗(yàn)。但是ADCON再次設(shè)置時(shí)可以啟動(dòng)ADC轉(zhuǎn)換,手冊(cè)上好像講是啟動(dòng)規(guī)則轉(zhuǎn)換,因?yàn)闆](méi)有度過(guò)注入轉(zhuǎn)換所以規(guī)則轉(zhuǎn)換可以設(shè)置些位,也可以設(shè)置ADCx_CR2寄存器器中的外部觸發(fā)來(lái)啟動(dòng),規(guī)則通道則是先設(shè)置EXTSEL[2:0]位,如果設(shè)置成111即軟件觸發(fā),后設(shè)置位20EXTTRIG位允許外部事件觸發(fā),最后設(shè)置位22SWSART來(lái)啟動(dòng)規(guī)則軟件觸發(fā),而注入觸發(fā)則同樣設(shè)置CR2寄存器中的某些對(duì)應(yīng)位來(lái)啟動(dòng)。

ADC有很多模式,而雙ADC模式個(gè)人認(rèn)為比較經(jīng)典,或許見(jiàn)識(shí)有點(diǎn)少了。哈哈。這里不多說(shuō),為什么?沒(méi)有經(jīng)驗(yàn),實(shí)驗(yàn)儀提供的資源多,但是隨心的少。

SCAN模式,即掃描整個(gè)通道。如果規(guī)則通道組中有3個(gè)通道,則啟動(dòng)通道時(shí)轉(zhuǎn)換完第一個(gè)自動(dòng)轉(zhuǎn)換第二個(gè)再然后第三個(gè)后停止并產(chǎn)生一個(gè)EOC事件,如果使能了中斷則產(chǎn)生中斷。(以前對(duì)中斷頭疼,現(xiàn)在覺(jué)得就是個(gè)紙老虎)

CONT即單詞continue(本來(lái)看成count)當(dāng)設(shè)置了SCAN又設(shè)置了CONT時(shí)將循環(huán)的轉(zhuǎn)換通道,即上面轉(zhuǎn)換完三后繼續(xù)生第一個(gè)轉(zhuǎn)換。同樣的地方產(chǎn)生EOC。(應(yīng)該是的,沒(méi)有實(shí)踐不敢斷定)。

注入模式:一種是外部觸發(fā),優(yōu)先于規(guī)則,如果有外部觸發(fā)將打斷正在轉(zhuǎn)換的規(guī)則通道。直至完成。

自動(dòng)注入模式:即轉(zhuǎn)換完成規(guī)則通道后自動(dòng)的切換到注入通道執(zhí)行轉(zhuǎn)換。

當(dāng)然ADC還有很多,比如常常配合ADC的DMA。ADC時(shí)鐘,外部觸發(fā)的事件啊,等等細(xì)節(jié)。

配置ADC,這里不將時(shí)鐘的打開(kāi),以上串口也未講。

void ADC_Initial(void)

{

ADC_InitTypeDef ADC_InitStruct;

ADC_Cmd(ADC1,ENABLE); //啟動(dòng)ADC

System_Delay_us(100); //延時(shí)幾個(gè)ADC周期

ADC_ResetCalibration(ADC1); //重置ADC校驗(yàn)

while(ADC_GetResetCalibrationStatus(ADC1)); //等待重置完成

ADC_StartCalibration(ADC1); //校驗(yàn)ADC

while(ADC_GetCalibrationStatus(ADC1)); //等待校驗(yàn)完成

ADC_InitStruct.ADC_Mode=ADC_Mode_Independent; //獨(dú)立模式

ADC_InitStruct.ADC_ScanConvMode=DISABLE; //非掃描模式,當(dāng)有多個(gè)ADC通道須要轉(zhuǎn)換時(shí)可以使能此位

ADC_InitStruct.ADC_ContinuousConvMode=ENABLE; //連續(xù)轉(zhuǎn)換使能

ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; //外部觸發(fā)條件,這里為軟件觸發(fā)

ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right; //右對(duì)齊模式

ADC_InitStruct.ADC_NbrOfChannel=1; //規(guī)則通道的個(gè)數(shù),放在SQR寄存器的L[3:0]中

ADC_Init(ADC1,&ADC_InitStruct);

ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_239Cycles5); //開(kāi)啟通道10寫(xiě)入規(guī)則通道中,并設(shè)置第幾個(gè)轉(zhuǎn)換,轉(zhuǎn)換周期為239

}

以上函數(shù)可以參考庫(kù)手冊(cè)。

再執(zhí)行完ADC_Cmd(ADC1,ENABLE);這條語(yǔ)句就可以讀通道10的AD轉(zhuǎn)換值了。12位AD值在0~4096之間。然后將這些值打印到串口看其變化。你會(huì)發(fā)現(xiàn)變化波動(dòng)還是較大的。可能極差并不會(huì)太大。你可以自己進(jìn)行濾波。

昨天洗完澡回來(lái)后并無(wú)睡意,所以寫(xiě)了個(gè)濾波,但沒(méi)什么新意,只是不厭其煩的取平均值。最后可以使AD值變化最大的情況下只有一個(gè)值的變化,一般情況下采樣值都會(huì)是同一個(gè)值。但這樣就大大(很大)犧牲了采樣靈敏度。

不過(guò)這樣的采樣濾波不科學(xué)。有興趣的同學(xué)可以上網(wǎng)搜下常見(jiàn)的AD的10大軟件濾波程序。比較經(jīng)典。

以下是一個(gè)簡(jiǎn)單的濾波代碼。犧牲了速度。

#define GetValueTimes 30

#define DeleteValue 10

uint16_t ADC_GetValue(void)

{

uint8_t i,j;

uint16_t DigitalValue[GetValueTimes],SwapTreg;

uint32_t CalValue=0;

for(i=0;i

{

DigitalValue[i]=ADC_GetConversionValue(ADC1);

}

for(i=0;i

{

for(j=i+1;j

{

if(DigitalValue[i]>DigitalValue[j])

{

SwapTreg=DigitalValue[i];

DigitalValue[i]=DigitalValue[j];

DigitalValue[j]=SwapTreg;

}

}

}

for(i=DeleteValue,j=0;i

{

DigitalValue[j]=DigitalValue[i];

}

for(i=0;i

{

CalValue+=DigitalValue[i];

}

CalValue=CalValue/i;

return (uint16_t)CalValue;

}

#define SampleTimes 10

uint16_t MoveMix(void)

{

uint16_t SampleBuffer[SampleTimes];

uint8_t i,j;

uint32_t CalValue=0;

Lable: for(i=0;i

{

SampleBuffer[i]=ADC_GetValue();

}

for(i=0;i

{

for(j=i;j

{

if(abs(SampleBuffer[i]-SampleBuffer[j])>=20)goto Lable;

}

}

for(i=0;i

{

CalValue+=SampleBuffer[i];

}

CalValue/=i;

return (uint16_t)CalValue;

}

#define SampleTimes2 10

uint16_t MoreMix(void)

{

uint8_t i;

uint32_t CalValue=0;

for(i=0;i

{

CalValue+=MoveMix();

}

CalValue/=i;

return (uint16_t)CalValue;

}

#define SampleOver 5

uint16_t OverMix(void)

{

uint8_t i;

uint16_t OverValue[SampleOver];

Lable2: for(i=0;i

{

OverValue[i]=MoreMix();

}

for(i=0;i

{

if(OverValue[i]!=OverValue[i+1])goto Lable2;

}

return OverValue[0];

}


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀
關(guān)閉