It would be useful to have more context about why you would do this. It is also not clear from your question if you want the cropped areas to overlap; I assume you do not want that.
You could so something like:
library(terra)
r <- rast(volcano)
n <- 10
Get the starting cells of interest
rows <- seq(1, nrow(r), by=n)
cols <- seq(1, ncol(r), by=n)
cells <- cellFromRowColCombine(r, rows, cols)
Get the coordinates
# upper-left coordinates of the starting cells
xy <- xyFromCell(r, cells)
rs <- res(r)
xy[,1] <- xy[,1] - rs[1]/2
xy[,2] <- xy[,2] + rs[2]/2
# add the lower-right coordinates of the end cell
xy <- cbind(xy[,1], xy[,1] + n*rs[1], xy[,2] - n*rs[2], xy[,2])
And loop
x <- lapply(1:nrow(xy), function(i) {
crop(r, xy[i,])
})
Verify
e <- lapply(x, \(i) ext(i) |> as.polygons()) |> vect()
plot(r)
lines(e, col="blue", lwd=2)

sapply(x, dim) |> t() |> head()
# [,1] [,2] [,3]
#[1,] 10 10 1
#[2,] 10 10 1
#[3,] 10 10 1
#[4,] 10 10 1
#[5,] 10 10 1
#[6,] 10 10 1
Or use an alternative approach based on the start- and end-cell numbers (for this to work you need terra 1.5-25, currently the development version that you can install with install.packages('terra', repos='https://rspatial.r-universe.dev')
)
srows <- seq(1, nrow(r), by=n)
scols <- seq(1, ncol(r), by=n)
erows <- pmin(nrow(r), srows+n-1)
ecols <- pmin(ncol(r), scols+n-1)
scell <- cellFromRowColCombine(r, srows, scols)
ecell <- cellFromRowColCombine(r, erows, ecols)
cells <- cbind(scell, ecell)
x <- lapply(1:nrow(cells), function(i) {
e <- ext(r, cells[i,])
crop(r, e)
})