Чт ноя 02, 2017 14:06:52
uint8_t dma_answ[5] = {0};
void clock_init(){
RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_SW);
RCC->CR &= ~RCC_CR_PLLON;
RCC->CFGR |= RCC_CFGR_SW_PLL;
RCC->CFGR &= ~RCC_CFGR_PLLMULL;
RCC->CFGR |= RCC_CFGR_PLLMULL9;// | RCC_CFGR_PLLSRC ;
RCC->CR |= RCC_CR_PLLON | RCC_CR_HSEON;
while((RCC->CR & RCC_CR_PLLRDY)==0);
}
void SPI_Init(uint8_t lsbFirst, uint8_t clockPol, uint8_t clockEdg){
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // Тактирование альтернативных функций включено
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Тактирование порта А включено
//------- TEST-PIN ----------
GPIOA->CRH |= GPIO_CRH_MODE12; // Выход, 50 МГц
GPIOA->CRH &= ~GPIO_CRH_CNF12; // Общего назначения, push-pull
GPIOA->BSRR = GPIO_BSRR_BR12;
//----------
//------- CS-PIN ----------
GPIOA->CRL |= GPIO_CRL_MODE4; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF4; // Общего назначения, push-pull
GPIOA->BSRR = GPIO_BSRR_BS4; // Высокий уровень
//----------
//------- SCK-PIN ----------
GPIOA->CRL |= GPIO_CRL_MODE5; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF5;
GPIOA->CRL |= GPIO_CRL_CNF5_1; // Альтернативная функция, push-pull
//----------
//------- MISO-PIN ----------
GPIOA->CRL &= ~GPIO_CRL_MODE6; // Вход
GPIOA->CRL &= ~GPIO_CRL_CNF6;
GPIOA->CRL |= GPIO_CRL_CNF6_1; // Альтернативная функция, pull-up/pull-down
GPIOA->BSRR = GPIO_BSRR_BS6; // Высокий уровень
//----------
//------- MOSI-PIN ----------
GPIOA->CRL |= GPIO_CRL_MODE7; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF7;
GPIOA->CRL |= GPIO_CRL_CNF7_1; // Альтернативная функция, push-pull
//----------
SPI1->CR1 = 0x0000; // Обнуляем регистр конфигурации SPI1
SPI1->CR2 = 0x0000; // Обнуляем регистр конфигурации SPI1
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // Тактирование SPI1 включено
SPI1->CR1 = SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_MSTR; // Программное управление выводом CS, SPI1 в режиме ведущего
if(!lsbFirst) SPI1->CR1 &= ~SPI_CR1_LSBFIRST; // Старшим битом вперёд
else SPI1->CR1 |= SPI_CR1_LSBFIRST; // Младшим битом вперёд
if(!clockPol) SPI1->CR1 &= ~SPI_CR1_CPOL; // 0 - когда отпущена
else SPI1->CR1 |= SPI_CR1_CPOL; // 1 - когда отпущена
if(!clockEdg) SPI1->CR1 &= ~SPI_CR1_CPHA; // Выборка по переднему фронту
else SPI1->CR1 |= SPI_CR1_CPHA; // Выборка по заднему фронту
SPI1->CR2 |= SPI_CR2_RXDMAEN;
SPI1->CR1 |= SPI_CR1_BR_1 | SPI_CR1_BR_0 ; // Выбор делителя частоты тактирования шины APB2 (fAPB/16 = 2.25 МГц)
SPI1->CR1 |= SPI_CR1_SPE; // Работа SPI1 разрешена
NVIC_EnableIRQ(SPI1_IRQn);
}
void dma_spi_recive( uint8_t* data, uint8_t bytesNumber ){
RCC->AHBENR = RCC_AHBENR_DMA1EN;
DMA1_Channel2->CCR = 0x0F;
DMA1_Channel2->CPAR = (uint32_t) & SPI1->DR;
DMA1_Channel2->CMAR = (uint32_t) dma_answ;
DMA1_Channel2->CNDTR = bytesNumber;
DMA1_Channel2->CCR |= DMA_CCR2_PL_0 | DMA_CCR2_MINC | DMA_CCR2_TCIE | DMA_CCR2_EN;
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
}
uint8_t SPI_Read( uint8_t data, uint8_t bytesNumber ){
dma_spi_recive(dma_answ, bytesNumber);
ADI_PART_CS_LOW;
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = data;
for(uint8_t byte = 0; byte < bytesNumber; byte++ )
{
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = 0x00;
}
while ( SPI1->SR & SPI_SR_BSY );
ADI_PART_CS_HIGH;
return 1;
}
uint8_t SPI_Read( uint8_t data, uint8_t bytesNumber ){
dma_spi_recive(dma_answ, bytesNumber);
ADI_PART_CS_LOW;
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = data;
for(uint8_t byte = 0; byte < bytesNumber; byte++ )
{
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = 0x00;
}
while ( SPI1->SR & SPI_SR_BSY );
ADI_PART_CS_HIGH;
return 1;
}
uint32_t AD7190_GetRegisterValue(uint8_t registerAddress){
uint8_t registerWord = 0;
uint32_t buffer = 0;
registerWord = AD7190_COMM_READ | AD7190_COMM_ADDR( registerAddress );
//-- Проверяем, какой длины считываемый регистр ----------
if( registerAddress == AD7190_REG_STAT ||
registerAddress == AD7190_REG_ID ||
registerAddress == AD7190_REG_GPOCON ) // если регистры однобайтные
{
SPI_Read(registerWord, 1);
}
else // если регистры трёхбайтные
{
SPI_Read(registerWord, 3);
}
//----------
return buffer;
}
unsigned char AD7190_Init(void){
unsigned char status = 1;
unsigned long regVal = 0;
AD7190_Reset();
regVal = AD7190_GetRegisterValue(AD7190_REG_ID);
if( regVal != ID_AD7190)
{
return status = 0;
}
GPIOA->BSRR = GPIO_BSRR_BS12; // Высокий уровень
return status ;
}
void AD7190_Reset(void){
for( uint8_t byte = 0; byte <6; byte++ )
{
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = 0xFF;
} // Посылаем 40 импульсов для сброса
TIME_DelayUs(920);
}
int main(){
clock_init();
for(uint32_t i=0; i<720000; i++);
SPI_Init(0, 1, 1);
usart_init();
AD7190_Init();
AD7190_GetRegisterValue(AD7190_REG_CONF);
__enable_irq ();
while(1){
}
}
void DMA1_Channel2_IRQHandler(void){
if(DMA1->ISR & DMA_ISR_TCIF2){
DMA1_Channel2->CCR &= ~DMA_CCR2_EN;
// Flag = 1;
if(!(GPIOA->IDR & GPIO_IDR_IDR12)) GPIOA->BSRR = GPIO_BSRR_BS12;
else GPIOA->BSRR = GPIO_BSRR_BR12;
DMA1->IFCR = DMA_IFCR_CGIF2;
}
}
Пт ноя 03, 2017 10:39:25
In order
to reload a new number of data items to be transferred into the DMA_CNDTRx register, the
DMA channel must be disabled.
Ср ноя 08, 2017 13:57:50
DMA1_Channel2->CCR = 0x00;
#include "stm32f10x.h" // Device header
#include "AD7190.h"
#include "TIME.h"
#define DMA_EN DMA1_Channel2->CCR |= DMA_CCR2_EN
#define DMA_DIS DMA1_Channel2->CCR &= ~DMA_CCR2_EN
//--------- SPI -------
volatile uint8_t SpiByteCnt = 0;
uint8_t SpiDataRX[5] = {0};
uint8_t dma_answ[5] = {0};
void clock_init(){
RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_SW);
RCC->CR &= ~RCC_CR_PLLON;
RCC->CFGR |= RCC_CFGR_SW_PLL;
RCC->CFGR &= ~RCC_CFGR_PLLMULL;
RCC->CFGR |= RCC_CFGR_PLLMULL9;
RCC->CR |= RCC_CR_PLLON | RCC_CR_HSEON;
while((RCC->CR & RCC_CR_PLLRDY)==0);
}
void usart_init(){
RCC->APB2ENR |= RCC_APB2ENR_USART1EN; //USART1 Clock ON
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN; // GPIOA Clock ON. Alter function clock ON
USART1->BRR = 0xEA6; // Bodrate for 9600 on 72Mhz
USART1->CR1 |= USART_CR1_UE | USART_CR1_TE; // USART1 ON, TX ON, RX ON
GPIOA->CRH &= ~GPIO_CRH_CNF9; // Clear CNF bit 9
GPIOA->CRH |= GPIO_CRH_CNF9_1; // Set CNF bit 9 to 10 - AFIO Push-Pull
GPIOA->CRH |= GPIO_CRH_MODE9_0; // Set MODE bit 9 to Mode 01 = 10MHz
GPIOA->CRH &= ~GPIO_CRH_CNF10; // Clear CNF bit 9
GPIOA->CRH |= GPIO_CRH_CNF10_0; // Set CNF bit 9 to 01 = HiZ
GPIOA->CRH &= ~GPIO_CRH_MODE10; // Set MODE bit 9 to Mode 01 = 10MHz
// NVIC_EnableIRQ(USART1_IRQn); // USART1 interrupt enable
}
void usart_tx(uint8_t data){
USART1->DR = data;
while(!(USART1->SR & USART_SR_TC));
}
uint8_t SPI_Init(uint8_t lsbFirst, uint8_t clockPol, uint8_t clockEdg){
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // Тактирование альтернативных функций включено
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Тактирование порта А включено
//------- TEST-PIN ----------
GPIOA->CRH |= GPIO_CRH_MODE12; // Выход, 50 МГц
GPIOA->CRH &= ~GPIO_CRH_CNF12; // Общего назначения, push-pull
GPIOA->BSRR = GPIO_BSRR_BR12;
//----------
//------- CS-PIN ----------
GPIOA->CRL |= GPIO_CRL_MODE4; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF4; // Общего назначения, push-pull
GPIOA->BSRR = GPIO_BSRR_BS4; // Высокий уровень
//----------
//------- SCK-PIN ----------
GPIOA->CRL |= GPIO_CRL_MODE5; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF5;
GPIOA->CRL |= GPIO_CRL_CNF5_1; // Альтернативная функция, push-pull
//----------
//------- MISO-PIN ----------
GPIOA->CRL &= ~GPIO_CRL_MODE6; // Вход
GPIOA->CRL &= ~GPIO_CRL_CNF6;
GPIOA->CRL |= GPIO_CRL_CNF6_1; // Альтернативная функция, pull-up/pull-down
GPIOA->BSRR = GPIO_BSRR_BS6; // Высокий уровень
//----------
//------- MOSI-PIN ----------
GPIOA->CRL |= GPIO_CRL_MODE7; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF7;
GPIOA->CRL |= GPIO_CRL_CNF7_1; // Альтернативная функция, push-pull
//----------
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // Тактирование SPI1 включено
SPI1->CR1 = SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_MSTR; // Программное управление выводом CS, SPI1 в режиме ведущего
if(!lsbFirst) SPI1->CR1 &= ~SPI_CR1_LSBFIRST; // Старшим битом вперёд
else SPI1->CR1 |= SPI_CR1_LSBFIRST; // Младшим битом вперёд
if(!clockPol) SPI1->CR1 &= ~SPI_CR1_CPOL; // 0 - когда отпушена
else SPI1->CR1 |= SPI_CR1_CPOL; // 1 - когда отпущена
if(!clockEdg) SPI1->CR1 &= ~SPI_CR1_CPHA; // Выборка по переднему фронту
else SPI1->CR1 |= SPI_CR1_CPHA; // Выборка по заднему фронту
SPI1->CR1 |= SPI_CR1_BR_1 | SPI_CR1_BR_0; // Выбор делителя частоты тактирования шины APB2 (fAPB/16 = 2.25 МГц)
SPI1->CR1 |= SPI_CR1_SPE; // Работа SPI1 разрешена
SPI1->CR2 = SPI_CR2_RXDMAEN;
return 1;
}
void dma_spi_recive( uint8_t bytesNumber ){
RCC->AHBENR = RCC_AHBENR_DMA1EN;
DMA1_Channel2->CCR = 0x00;
DMA1_Channel2->CPAR = (uint32_t) & SPI1->DR;
DMA1_Channel2->CMAR = (uint32_t) dma_answ;
DMA1_Channel2->CNDTR = bytesNumber;
DMA1_Channel2->CCR |= DMA_CCR2_PL_0 | DMA_CCR2_MINC | DMA_CCR2_TCIE;
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
}
int main(){
uint8_t init = 0, registerWord[5] = {0};
clock_init();
SPI_Init(0, 1, 1);
usart_init();
__enable_irq ();
while(1){
if(!init){
for( uint8_t byte = 0; byte <6; byte++ ){
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = 0xFF;
}
while ( SPI1->SR & SPI_SR_BSY );
TIME_DelayUs(920);
registerWord[0] = AD7190_COMM_READ | AD7190_COMM_ADDR( AD7190_REG_ID );
ADI_PART_CS_LOW;
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = registerWord[0];
while ( SPI1->SR & SPI_SR_BSY );
dma_spi_recive(1);
DMA_EN;
init = 1;
}
}
}
void DMA1_Channel2_IRQHandler (void)
{
if(DMA1->ISR & DMA_ISR_TCIF2){
ADI_PART_CS_HIGH;
if(!(GPIOA->IDR & GPIO_IDR_IDR12)) GPIOA->BSRR = GPIO_BSRR_BS12;
else GPIOA->BSRR = GPIO_BSRR_BR12;
DMA_DIS;
NVIC_DisableIRQ(DMA1_Channel2_IRQn);
DMA1->IFCR = DMA_IFCR_CGIF2;
}
}
#include "stm32f10x.h"
#define AD7195_CS_HIGH GPIOA->BSRR |= GPIO_BSRR_BS4
#define AD7195_CS_LOW GPIOA->BSRR |= GPIO_BSRR_BR4
#define DMA_SPI_TX_ENABLE DMA1_Channel3->CCR |= DMA_CCR3_EN;
#define DMA_SPI_TX_DISABLE DMA1_Channel3->CCR &= ~DMA_CCR3_EN;
#define DMA_SPI_RX_ENABLE DMA1_Channel2->CCR |= DMA_CCR2_EN;
#define DMA_SPI_RX_DISABLE DMA1_Channel2->CCR &= ~DMA_CCR3_EN;
uint8_t GlobalVar_SPI_Received = 0, get[5];
void GPIO_INIT(){
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // Тактирование альтернативных функций включено
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Тактирование порта А включено
//------- TEST-PIN ----------
GPIOA->CRH |= GPIO_CRH_MODE12; // Выход, 50 МГц
GPIOA->CRH &= ~GPIO_CRH_CNF12; // Общего назначения, push-pull
GPIOA->BSRR = GPIO_BSRR_BR12;
//----------
//------- CS-PIN ----------
GPIOA->CRL |= GPIO_CRL_MODE4; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF4; // Общего назначения, push-pull
GPIOA->BSRR = GPIO_BSRR_BS4; // Высокий уровень
//----------
//------- SCK-PIN ----------
GPIOA->CRL |= GPIO_CRL_MODE5; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF5;
GPIOA->CRL |= GPIO_CRL_CNF5_1; // Альтернативная функция, push-pull
//----------
//------- MISO-PIN ----------
GPIOA->CRL &= ~GPIO_CRL_MODE6; // Вход
GPIOA->CRL &= ~GPIO_CRL_CNF6;
GPIOA->CRL |= GPIO_CRL_CNF6_1; // Альтернативная функция, pull-up/pull-down
GPIOA->BSRR = GPIO_BSRR_BS6; // Высокий уровень
//----------
//------- MOSI-PIN ----------
GPIOA->CRL |= GPIO_CRL_MODE7; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF7;
GPIOA->CRL |= GPIO_CRL_CNF7_1; // Альтернативная функция, push-pull
//----------
AD7195_CS_HIGH;
}
void SPI_INIT(){
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // Тактирование SPI1 включено
SPI1->CR1 = SPI_CR1_SSI | SPI_CR1_SSM | // Программное управление выводом CS
SPI_CR1_BR_1 | SPI_CR1_BR_0 | // Выбор делителя частоты тактирования шины APB2
SPI_CR1_CPOL | SPI_CR1_CPHA | SPI_CR1_MSTR; // 1 - когда CLK отпущена, выборка по заднему фронту, SPI1 в режиме ведущего
SPI1->CR1 |= SPI_CR1_SPE; // Работа SPI1 разрешена
}
void dma_spi_tx(uint8_t * data, uint16_t size) {
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel3->CPAR = (uint32_t) & SPI1->DR;
DMA1_Channel3->CMAR = (uint32_t) data;
DMA1_Channel3->CNDTR = size;
DMA1_Channel3->CCR = DMA_CCR3_PL_0 | DMA_CCR3_MINC | DMA_CCR3_DIR | DMA_CCR3_TCIE;
SPI1->CR2 |= SPI_CR2_TXDMAEN;
NVIC_EnableIRQ(DMA1_Channel3_IRQn);
}
void SPI_SendData(uint8_t *data, uint8_t size) {
dma_spi_tx(data, size);
AD7195_CS_LOW;
DMA_SPI_TX_ENABLE;
}
void dma_spi_rx(uint8_t * data, uint16_t size) {
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel2->CPAR = (uint32_t) & SPI1->DR;
DMA1_Channel2->CMAR = (uint32_t) data;
DMA1_Channel2->CNDTR = size;
DMA1_Channel2->CCR = DMA_CCR2_PL_0 | DMA_CCR2_MINC | DMA_CCR2_TCIE;
SPI1->CR2 |= SPI_CR2_RXDMAEN;
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
}
void SPI_ReciveData(uint8_t *data, uint8_t size) {
dma_spi_rx(data, size);
AD7195_CS_LOW;
DMA_SPI_RX_ENABLE;
}
int main(void){
uint8_t spi_data[]={0x60};
__enable_irq ();
GPIO_INIT();
SPI_INIT();
for( uint8_t byte = 0; byte <6; byte++ ){
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = 0xFF;
}
while ( SPI1->SR & SPI_SR_BSY );
for(uint32_t i=0; i<72000; i++);
SPI_SendData(spi_data, 1);
while(1){
}
}
void DMA1_Channel3_IRQHandler(void) {
if (DMA1->ISR & DMA_ISR_TCIF3) {
while ( SPI1->SR & SPI_SR_BSY );
AD7195_CS_HIGH;
DMA_SPI_TX_DISABLE;
SPI1->CR2 |= SPI_CR2_TXDMAEN;
SPI_ReciveData(get, 1);
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = 0x00;
DMA1->IFCR = DMA_IFCR_CTCIF3;
}
}
void DMA1_Channel2_IRQHandler(void) {
if (DMA1->ISR & DMA_ISR_TCIF2) {
while ( SPI1->SR & SPI_SR_BSY );
AD7195_CS_HIGH;
GPIOA->BSRR |= GPIO_BSRR_BS12;
GlobalVar_SPI_Received = 1;
DMA_SPI_RX_DISABLE;
DMA1->IFCR = DMA_IFCR_CTCIF2;
}
}
Чт ноя 09, 2017 07:28:48
Пн ноя 13, 2017 06:50:07
Вт окт 09, 2018 12:27:27
void spi2_gpio_init(void){
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN;
//------- CS_OLED, RESET_OLED, POWER_OLED, D/C#_OLED ----------
GPIOB->CRH |= (GPIO_CRH_MODE12 | GPIO_CRH_MODE11 | GPIO_CRH_MODE10); // Выход, 50 МГц
GPIOB->CRH &= ~(GPIO_CRH_CNF12 | GPIO_CRH_CNF11 | GPIO_CRH_CNF10); // Общего назначения, push-pull
GPIOB->CRL |= GPIO_CRL_MODE2; // Выход, 50 МГц
GPIOB->CRL &= ~GPIO_CRL_CNF2; // Общего назначения, push-pull
GPIOB->BSRR = GPIO_BSRR_BS12; // Высокий уровень
//----------
//--- CS_FLASH, CS_EEPROM ----------
GPIOC->CRL |= (GPIO_CRL_MODE5 | GPIO_CRL_MODE4); // Выход, 50 МГц
GPIOC->CRL &= ~(GPIO_CRL_CNF5 | GPIO_CRL_CNF4); // Общего назначения, push-pull
GPIOC->BSRR = GPIO_BSRR_BS5 | GPIO_BSRR_BS4; // Высокий уровень
//----------
//--- SCK, MOSI ----------
GPIOB->CRH |= (GPIO_CRH_MODE13 | GPIO_CRH_MODE15); // Выход, 50 МГц
GPIOB->CRH &= ~(GPIO_CRH_CNF13 | GPIO_CRH_CNF15);
GPIOB->CRH |= (GPIO_CRH_CNF13_1 | GPIO_CRH_CNF15_1); // Альтернативная функция, push-pull
//----------
//------- MISO-PIN ----------
GPIOB->CRH &= ~GPIO_CRH_MODE14; // Вход
GPIOB->CRH &= ~GPIO_CRH_CNF14;
GPIOB->CRH |= GPIO_CRH_CNF14_0; // floating
//----------
/*
* 2-line unidirectional data mode
* CRC disabled
* 8bit data format
* Full duplex
* Software slave management enabled
* MSB transmitted first
* fPCLK/2
* Master configuration
* SCK to 1 when idle
* The second clock transition is the first data capture edge
*/
void spi_init(void){
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
SPI2->CR1 = SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_BR_0 | SPI_CR1_MSTR | SPI_CR1_CPOL | SPI_CR1_CPHA | SPI_CR1_SPE;
GPIOB->BSRR = GPIO_BSRR_BS13; //SCK pull-up
}
void dma_spi2_tx(uint8_t *data, uint16_t size) {
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel5->CCR = 0;
DMA1_Channel5->CPAR = (uint32_t) &SPI2->DR; //Указываем адрес периферии
DMA1_Channel5->CMAR = (uint32_t) &data[0]; //Указываем адрес в памяти
DMA1_Channel5->CNDTR = size; //Количество пересылаемых значений
DMA1_Channel5->CCR = DMA_CCR5_DIR | //Указываем направление передачи данных, из памяти в периферию
DMA_CCR5_MINC | //Адрес памяти инкрементируем после каждой пересылки.
DMA_CCR5_PL | //Приоритет - очень высокий
DMA_CCR5_TCIE | //Разрешаем прерывание по окончанию передачи
DMA_CCR5_EN; //Разрешаем работу 4-го канала DMA
SPI2->CR2 = SPI_CR2_TXDMAEN;
NVIC_EnableIRQ(DMA1_Channel5_IRQn);
}
void dma_spi2_rx(uint8_t *data, uint16_t size) {
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel4->CCR = 0;
DMA1_Channel4->CPAR = (uint32_t) &SPI2->DR; //Указываем адрес периферии
DMA1_Channel4->CMAR = (uint32_t) &data[0]; //Указываем адрес в памяти
DMA1_Channel4->CNDTR = size; //Количество пересылаемых значений
DMA1_Channel4->CCR = DMA_CCR4_MINC | //Адрес памяти инкрементируем после каждой пересылки.
DMA_CCR4_PL | //Приоритет - очень высокий
DMA_CCR4_HTIE | //Разрешаем прерывание по передаче половины буфера
DMA_CCR4_TCIE | //Разрешаем прерывание по окончанию передачи
DMA_CCR4_TEIE | //Разрешаем прерывание по окончанию передачи
DMA_CCR4_EN; //Разрешаем работу 4-го канала DMA
SPI2->CR2 = SPI_CR2_RXDMAEN;
NVIC_EnableIRQ(DMA1_Channel4_IRQn);
}
void SPI_SendData(uint8_t *data, uint16_t size) {
dma_spi2_tx(data, size);
}
void SPI_ReciveData(uint8_t *data, uint16_t size) {
dma_spi2_rx(data, size);
SPI_SendData(data, size);
}
void DMA1_Channel5_IRQHandler() {
if (DMA1->ISR & DMA_ISR_TCIF5 ) {
while(!(SPI2->SR & SPI_SR_TXE));
while (SPI2->SR & SPI_SR_BSY);
All_Modules_Deselect();
DMA1_Channel5->CCR &= ~DMA_CCR5_EN;
SPI2->CR2 &= ~ SPI_CR2_TXDMAEN;
DMA1->IFCR |= DMA_IFCR_CTCIF5;
}
}
void DMA1_Channel4_IRQHandler(void) {
if (DMA1->ISR & DMA_ISR_HTIF4 ) {
// Уведомляем, что данные приняты
GlobalVar_SPI_Received = 1;
DMA1_Channel4->CCR &= ~DMA_CCR4_EN;
DMA1->IFCR |= DMA_IFCR_CHTIF4;
}
if (DMA1->ISR & DMA_ISR_TCIF4 ) {
// Уведомляем, что данные приняты
GlobalVar_SPI_Received = 1;
DMA1_Channel4->CCR &= ~DMA_CCR4_EN;
DMA1->IFCR |= DMA_IFCR_CTCIF4;
}
if (DMA1->ISR & DMA_ISR_TEIF4 ) {
// Уведомляем, что данные приняты
GlobalVar_SPI_Received = 1;
DMA1_Channel4->CCR &= ~DMA_CCR4_EN;
DMA1->IFCR |= DMA_IFCR_CTEIF4;
}
}
Вт окт 09, 2018 12:51:02
DMA1->IFCR = DMA_IFCR_CHTIF4;
Вт окт 09, 2018 13:06:22
Вт окт 09, 2018 13:43:25
void SPI_SendData(uint8_t *data, uint16_t size) {
dma_spi2_tx(data, size); // SPI2->CR2 = SPI_CR2_TXDMAEN;
}
void SPI_ReciveData(uint8_t *data, uint16_t size) {
dma_spi2_rx(data, size); // SPI2->CR2 = SPI_CR2_RXDMAEN;
SPI_SendData(data, size);
}
Вт окт 09, 2018 13:47:07
Вт окт 09, 2018 13:50:00
Вт окт 09, 2018 14:06:33
Вт окт 09, 2018 14:11:24
Вт окт 09, 2018 15:35:49
Вт окт 09, 2018 18:14:32
Вт окт 09, 2018 19:07:03
Ср окт 10, 2018 06:25:36
!!!При чем тут порядок, у тебя вызов SPI_SendData() сбрасывает SPI_CR2_RXDMAEN.
Вс апр 21, 2019 19:43:49
void Init_DMA5 (void) // SPI2 Transmitte
{
RCC->AHBENR |= RCC_AHBENR_DMA1EN; // Enable Clock DMA1
DMA1_Channel5->CCR = 0x0000; // Disable DMA
DMA1_Channel5->CPAR = (uint32_t)&(SPI2->DR); // Periferal Adress
DMA1_Channel5->CMAR = (uint32_t)&(ScreenBuf [(AdressLED << 4)]); // Memory Adress
DMA1_Channel5->CNDTR = DMA_BUFF_SIZE; // Number of data to transfer
DMA1_Channel5->CCR = DMA_CCR1_DIR | // Data transfer direction - Read from memory
DMA_CCR1_MINC | // Memory increment mode enabled
DMA_CCR1_TCIE | // Transfer complete interrupt enable
DMA_CCR1_EN; // Enable DMA1
SPI2->CR2 |= SPI_CR2_TXDMAEN; // Tx buffer DMA enabled
NVIC_EnableIRQ(DMA1_Channel5_IRQn); // Enable Interrupt DMA1 channel CH5 in NVIC
NVIC_SetPriority(DMA1_Channel5_IRQn,14);
}
void DMA1_Channel5_IRQnHandler (void)
{
static u16 CntDMA1CH5;
if (CntDMA1CH5++ & 0x00F0) { GPIOA->BSRR = GPIO_BSRR_BR12; } // PA12 - LED RED
else { GPIOA->BSRR = GPIO_BSRR_BS12; }
while (!(SPI2->SR & SPI_SR_TXE));
while (SPI2->SR & SPI_SR_BSY);
if (DMA1->ISR & DMA_ISR_TCIF5) // Check Transfer Complete flag
{
DMA1->IFCR |= DMA_IFCR_CTCIF5; // Clear Transfer Complete flag
}
DMA1->IFCR |= DMA_IFCR_CGIF5; // Channel 5 Global interrupt clear
}
Пн апр 22, 2019 13:43:04
Пн апр 22, 2019 16:15:35
// ----------
void ReStart_DMA5 (void) // SPI2 Transmitte
{
DMA1_Channel5->CCR &= ~DMA_CCR1_EN; // Disable DMA
DMA1_Channel5->CPAR = (uint32_t) &(SPI2->DR); // Periferal Adress
DMA1_Channel5->CMAR = (uint32_t) &(ScreenBuf [(AdressLED << 4)]); // Memory Adress
DMA1_Channel5->CNDTR = DMA_BUFF_SIZE; // Number of data to transfer
DMA1_Channel5->CCR |= DMA_CCR1_EN; // Enable DMA
}